Dave Normington

Software Engineer

Unit Testing With Mocks

Jun 16, 2018

At Assert(js) 2018, Justin Searls (@searls) gave a great and balanced talk about the value of mocking. Stop reading. Watch the talk. All of it. Or read my Too long didn’t watch summary for the more impatient among you but the talk is much more entertaining.

Before Justin’s talk I fell into the “avoid mocking unless absolutely necessary” camp. I didn’t consider the pros and cons of either approach. I didn’t think of the scenarios in which using mocks would actually improve my tests.

I had read Martin Fowler’s UnitTest article and often sited it, refering to the benefit of “socialable” unit tests. These are closer to the real world usage of the units and were blackbox tests meaning that your tests weren’t aware of the implementation details. This meant that I could refactor the unit without having to change my tests at the same time.

But there were some pain points. If I tested A that depended on B which in turn also depended on C, my test would be covering B and C. But B also had it’s own unit tests and those also covered C. And finally C would have it’s own unit tests. It felt that in some cases, despite the tests being at different levels of abstraction, that some cases were repeated throughout.

There are also the times that when I changed the behaviour of C, then tests for A and B would also fail. Sometimes I would have to modify A and B to pass new arguments along but not as often as you might think. There is this subtle coupling between the tests of A + B and the behaviour of C. Even though the tests don’t reference the implementation of C, I have to change the tests when C changes.

That starts to sound like a violation of the Single Responsibility Principle (SRP). Perhaps the cases I’m testing in A and B should really live in the test suite for C. Then the tests in A could simply check that B was called by using a mock. Likewise in the tests for B a mock can help to verify that C is being called correctly.

What are the benefits of this approach?

What are the drawbacks?