How to verify a method actually gets called – without a mocking framework

hard-labor

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.

explosion

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.

side effects

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.

function

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

Your email address will not be published. Required fields are marked *

*

Show Buttons
Hide Buttons