- A Web of Objects
- Values and Objects
- Follow the Messages
- Tell, Don't Ask
- But Sometimes Ask
- Unit-Testing the Collaborating Objects
- Support for TDD with Mock Objects
Support for TDD with Mock Objects
To support this style of test-driven programming, we need to create mock instances of the neighboring objects, define expectations on how they're called and then check them, and implement any stub behavior we need to get through the test. In practice, the runtime structure of a test with mock objects usually looks like Figure 2.6.
Figure 2.6 Testing an object with mock objects
We use the term mockery2 for the object that holds the context of a test, creates mock objects, and manages expectations and stubbing for the test. We'll show the practice throughout Part III, so we'll just touch on the basics here. The essential structure of a test is:
- Create any required mock objects.
- Create any real objects, including the target object.
- Specify how you expect the mock objects to be called by the target object.
- Call the triggering method(s) on the target object.
- Assert that any resulting values are valid and that all the expected calls have been made.
The unit test makes explicit the relationship between the target object and its environment. It creates all the objects in the cluster and makes assertions about the interactions between the target object and its collaborators. We can code this infrastructure by hand or, these days, use one of the multiple mock object frameworks that are available in many languages. The important point, as we stress repeatedly throughout this book, is to make clear the intention of every test, distinguishing between the tested functionality, the supporting infrastructure, and the object structure.