Test doubles tips

Author’s note: My opinion about the best way to use mock objects changes every few months. I’ll try some mocks, see that they work well, so I start using more mocks, and they’ll start getting in the way, so I back off, and then I think, “Let’s try some mocks.” This cycle has been going for years, and I have no reason to think it’s going to change anytime soon.

However, some guidelines always hold. Let’s see what they are.

The ownership rule

We don’t mock what we don’t own. Instead, we use test doubles only to replace methods that are part of the application and not part of an external framework.

Note: We violated this rule in this chapter when we stubbed ActiveRecord methods like update_attributes. Again, Don’t mock what we don’t own.

Frameworks and mocks

One reason to mock only methods we control is, well, that we control them. One danger in mocking methods is that the mock either doesn’t receive or doesn’t return a reasonable value from the replaced method. If the method in question belongs to a third-party framework, the chance that it will change without us knowing increases, and thus the test becomes more brittle.

More importantly, mocking a method we don’t own couples the test to the third-party framework’s internal details. By implication, this means the method being tested is also coupled to those internal details. That is bad, not just if the third-party tool changes, but also if we want to refactor the code. The dependency will make that change more complicated.

External services and mocks

In most cases, the solution is to create a method or class in the application that calls the third-party tool and stubs that method (while also writing tests to ensure that the wrapper does the right thing). We’ll see a larger example of this technique in the chapter “Testing External Services”. However, in a smaller case, we can do this easily as follows:

Get hands-on with 1200+ tech skills courses.