You have busted your bum writing a solid
MagnificentValidation validation method that checks the input data for a whole slew of data manipulation methods. And you, of course, covered it with unit tests so nobody, not even you, can accidentally mess up the validation logic without it being noticed.
But wait… what if…
How do you ensure that your rock solid data validation is not inadvertently deactivated? You can’t for the life of you imagine why anybody would do that, but hey, (sh)it happens!
You want a safety net. One that ensures that all data manipulation methods actually do call your
Obviously that means that you need to write a test for those data manipulation methods. That test needs to call a data manipulation method and verify that
MagnificentValidation was called.
Sounds easy enough. And it is when you use a mocking framework. But what if you don’t? What do you then put in the assert part of such a test?
MagnificentValidation is called
MagnificentValidation is called depends entirely on its implementation.
MagnificentValidation throws exceptions
Validation methods throwing exceptions are usually the easiest to check for being called. All you need to do is feed the calling method invalid data and check that the exception is actually thrown.
Using MSTest you would need to use the
ExpectedException attribute, or code a
try catch yourself. Using NUnit, or any other unit testing framework whose
Assert class supports checking for exceptions being thrown, you can use its equivalent of an
Assert.Throws() assertion in your test.
See Testing strategy for validation and action methods for an example.
MagnificentValidation has other side effects than exceptions
Validation methods that have other side effects than exceptions are a little harder to check for being called. But not by much. Instead of checking for an exception being thrown, you now just call
DataManipulation and then check for the expected side effect, for example an ErrorText property that given the implementation of
MagnificentValidation should no longer have an empty string as its value.
See Verify a validation method is called that doesn’t throw exceptions for an example.
MagnificentValidation does not have side effects but returns a result
Validation methods that do not have any side effects at all but “just” return a result are hardest to check for being called. The result they return is after all not visible to your test, but only to the calling method.
That means that the only way you can check that
YourDataManipulation method calls
MagnificentValidation is by the behavior you expect from
YourDataManipulation given invalid input.
Yup, that means “repeating” the implementation of a test on methods calling
MagnificentValidation. May feel soggy, but is very much advised as the intention of the test is wildly different from the actual behavioral tests.
Tests do more than verify behavior. They also serve as documentation of every aspect of your class’ behavior. Each test represents a different piece of knowledge about your class. Something that should be reflected in the name of the test method. If two tests happen to have the (almost) same implementation, that is … well … an implementation detail.
This was first discussed in How can you check a validation method is called if it just returns an error code.
While mocking frameworks may make it easy to verify that a method was called, DIYing such checks isn’t exactly rocket science either if you know how to go about it.
That’s it. Enjoy!
What code had you wondering how to test it? I’d love hearing from you by email or in the comments below. I read everything and will try to help where and as best I can.