Understanding When Test Doubles Are Appropriate
Explore how to effectively use test doubles such as mocks and stubs in Java unit testing. Understand when mocks should be avoided to prevent poor test quality, including avoiding mocks for code you don’t own and value objects. Learn how dependency injection enables test doubles and why overusing mocks can hinder refactoring. By the end, you'll know how to apply test doubles appropriately to write maintainable and robust tests.
Mock objects are a useful kind of test double, as we have seen. But they are not always the right approach. There are some situations where we should actively avoid using mocks. These situations include overusing mocks, using mocks for code we don’t own, and mocking value objects. We’ll look at these situations next. Then, we’ll recap with general advice for where mocks are typically useful. Let’s start by considering the problems caused when we overuse mock objects.
The pitfall of overusing mock objects
At first glance, using mock objects seems to solve a number of problems for us. Yet if used without care, we can end up with very poor-quality tests. To understand why, let’s go back to our basic definition of a TDD test. It’s a test that verifies behaviors and is independent of implementations. If we use a mock object to stand in for a genuine abstraction, then we’re complying with that.
The potential problem happens because it’s all too easy to create a mock object for an implementation detail, not an abstraction. If we do this, we end up locking our code into a specific implementation and structure. Once a test is coupled to a specific implementation detail, then changing that implementation requires a change to the test. If the new implementation has ...