At times in the testing process you want to make sure that a certain method on a mocked object _does_not_ get called. For example, perhaps you’re performing some validation on a object and the object fails the validation rules. At this point you’d want the call to pop back up the stack to the caller who can handle the proper validation violations.
An example of this is a class in the controller of an ASP.NET MVC app. This controller performs the validation and if and only if everything is good will it call the Save method on the service layer (which then in turns does a whole bunch of other junk).
In my test I want to make sure my validation works and that messages are added to the ModelState Error collection – this being a state based test. At the same time I also want to make sure that my service layers “Save” method is _never_ called. This is an interaction based test.
Here’s an example test:
[Test] public void Controller_should_not_be_able_to_add_a_customer_with_a_empty_name() { // Arrange var form = new FormCollection { { "FirstName", "" } }; // Act var result = controller.Add(1, form); // 1 is the customer id // Assert // State test Assert.That(controller.ViewData.ModelState["FirstName"].Errors.Count, Is.EqualTo(1)); // Interaction Test mockService.AssertWasNotCalled(x => x.Save(Arg<int>.Is.Anything, Arg<Customer>.Is.Anything)); }
In the code above we are wanting to make sure that the controllers FirstName error count is equal to 1 because we should not be allowing customers with empty names to enter our system. However, just because we captured an error message in the model state this does not mean that we have not mistakenly called the Save method on the service and accidentally saved the user in an invalid state. Therefore the following line prevents this test from passing if the service.save() method was called:
mockService.AssertWasNotCalled(x => x.Save(Arg<int>.Is.Anything, Arg<CustomerRecord>.Is.Anything));
Note the generic Arg<T> parameter. This allows me to tell Rhino Mocks that the argument can be any int value, and the customer could be any customer value. I don’t care which customer, Id, or etc it is, I _do_not_ want this method called whatsoever. I can also provide much more restrictive values with the generic Arg<T> as well, but at this level we’re capturing any possible value passed into the method. Essentially saying: make sure this method never gets called.
If that method is called, an ExpectationViolationException will be called: H
Rhino.Mocks.Exceptions.ExpectationViolationException: Expected that ICustomerService.Save(anything, anything); would not be called, but it was found on the actual calls made on the mocked object.
Happy mocking. (pun intended)
Coach Outlet Online says
http://www.mycoachoutletstoreonline.com
Coach Factory Online says
Business coaching is an informal, open affair. You will meet with the coach and he will assess your business’s needs, and then tailor his services to your precise requirements.
Coach Factory Outlet says
http://buycoachfactoryoutletsz.com