Unit Testing – Importance of Not Testing Dependencies

dependency-injectionmockingtestingunit testing

I understand the value of automated testing and use it wherever the problem is well-specified enough that I can come up with good test cases. I've noticed, though, that some people here and on StackOverflow emphasize testing only a unit, not its dependencies. Here I fail to see the benefit.

Mocking/stubbing to avoid testing dependencies adds complexity to the tests. It adds artificial flexibility/decoupling requirements to your production code to support mocking. (I disagree with anyone who says this promotes good design. Writing extra code, introducing things like dependency injection frameworks, or otherwise adding complexity to your codebase to make things more flexible/pluggable/extensible/decoupled without a real use case is overengineering, not good design.)

Secondly, testing dependencies means that critical low-level code that's used everywhere gets tested with inputs other than those that whoever wrote its tests explicitly thought of. I've found plenty of bugs in low-level functionality by running unit tests on high level functionality without mocking out the low-level functionality it depended on. Ideally these would have been found by the unit tests for the low-level functionality, but missed cases always happen.

What's the other side to this? Is it really important that a unit test doesn't also test its dependencies? If so, why?

Edit: I can understand the value of mocking external dependencies like databases, networks, web services, etc. (Thanks to Anna Lear for motivating me to clarify this.) I was referring to internal dependencies, i.e. other classes, static functions, etc. that don't have any direct external dependencies.

Best Answer

It's a matter of definition. A test with dependencies is an integration test, not a unit test. You should also have an integration test suite. The difference is that the integration test suite may be run in a different testing framework and probably not as part of the build because they take longer.

For our product: Our unit tests are run with each build, taking seconds. A subset of our integration tests runs with each check-in, taking 10 minutes. Our full integration suite is run each night, taking 4 hours.

Related Topic