Hard labor
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.
Yes!
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 MagnificentValidation
method.
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?
Verifying MagnificentValidation
is called
Verifying that MagnificentValidation
is called depends entirely on its implementation.
When 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.
When 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.
When 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.
Conclusion
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.
Leave a Reply