Question

My class has a dependency which I mocked in my unit tests. I was getting a null reference exception in a place where it didn't make much sense to me.

I just realised it was because I didn't set up my mocked dependency. This dependency is tested but it doesn't connect to anything like file system or data sources.

I only wanted to test my new code in this new class but I guess in this case it is better not to mock at all.

Is this conclusion correct?

Was it helpful?

Solution

Correct. You should mock things that depend on anything persistent or external in order to prevent the test from depending on anything persistent or external.

If the dependency does not depend on anything persistent or external, the only benefit you gain from mocking it is that the test will work properly even if the dependency is wrong - but that's assuming the mock works properly. For that you need to either:

  1. Write a mock that emulates the dependency completely.

  2. Write a mock that emulates the dependency for the specific cases that will be used in the test.

The first option is outright ridiculous - why should your mock be any better than the original dependency? After all, it's safe to assume much more effort was invested in the original dependency than in the mock...

The second option means your mock knows the exact details of the implementation - otherwise you won't know how the implementation uses the dependency so you don't know how to mock those specific uses. This means the test does not serve one of the main purposes of unit tests - verifying that the code works properly after changes to the implementation.

The drawbacks of mocking are too big and the advantages are too small - especially considering that you can always run the dependency's tests to check if it works properly...

OTHER TIPS

It sounds like it's working in your case, but it's not true in general that the only reason to stub or mock is to get external data sources and such out of your test's hair. Other reasons include

  • a method might be slow all by itself
  • it may be difficult to come up with the right parameters to pass to another class's method to get it to return the value that you need for a test of your method
  • the method you're testing needs an instance of another class which changes a lot, and you don't want your tests of the caller to break when the callee changes
  • the method you depend on is complicated enough to need its own tests, fully testing your method without stubbing or mocking means fully testing the methods that it calls (within your method's own tests), and this results in duplication between tests of your class and tests of the methods it calls
  • you're doing TDD from the outside in and you haven't written the callee yet, just designed its interface!

It depends: can you consider the dependency to actually just be a private implementation detail? If so, then mocking it only makes your test more brittle.

However, if it's a dependency that is actually injected into your SUT, then it absolutely should be replaced with a test double in your unit test.

The SUT should be the only interesting thing in your test. Everything else should be rote, boring, and constant, in order to ensure your SUT is operating in optimal conditions (for the scenario being tested).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top