We ended Part II with an inner Builder for
Address, which forced us to revert to specifying seemingly arbitrary values in each test that needed to build an
What I’ve usually seen at this point is pulling the Address objects into constants in each test class. As the test suite grows, the number of
private static final Address WHATEVER_ADDRESS = ...; grows and grows. Doing that makes it hard to keep control over your test data, especially in a large codebase. A minor change to Address, such as a new invariant or an added field, could cause cascading changes to keep all those objects valid.
To avoid that, the next step is actually a very simple one, and boils down to centralizing the definition and creation of an
Address with an Object Mother.
4) Introducing an Object Mother
An Object Mother is a type of Factory used to create example objects for testing. Let’s see it in action:
The Mother controls the values that constitute an example
Address. Now, when a test needs an
Address it asks the Mother for one. Your Mother could return fully initialized
Address objects, but instead we have chosen to have it return Builders. This powerful variation allows a test to get a basic example object, and then modify it depending on what it is testing.
Give your Mother class the ability to build objects with various states as appropriate. In our case, we currently have the need for a basic, valid address, and a Hawaiian address. But, be wary of creating a different factory method for every example object you need. That may be a bit overkill. I’d say to only create factory methods for things that represent core use cases and not one for each edge case that you test. For example, if I wanted to test what happens when
state is empty, I’d do
address().state("").build() over creating an
addresWithoutAState() factory method in the Mother.
Whew, that’s it! Thanks for making it this far. If you skipped Parts I or II, I’d recommend going back to see the entire journey. We teased out a nice pattern for managing test data using the Builder pattern + Object Mothers. In doing so, we improved the design of our production code by making
Address immutable and avoiding a sketchy constructor with a lot of parameters.