Over the past few months on my project, a pattern emerged for using Builders and Object Mothers to build-up objects for unit testing. We were able to keep our tests minimal and clean, decouple test code from production code, and solve some design issues such as constructors with too many parameters. In this multi-part series, I will take you through the evolution of the pattern over a series of refactorings.

## The Scenario:

Note: This is contrived for simplicity

The basics: We are building a system that schedules shipments of widgets to a specified address.

The interesting bit: We have an Address class that we use quite often in our tests. By “use”, I mean instantiate one with some valid data to either exercise it or assert against it.

## 1) Initial Code:

The two hot spots here are the Address constructor and the customization of the Address fields in the tests.

1. It has too many parameters - four! (And you could imagine a real Address object having at least a couple more) And, multiple parameters in a row of the same type is even worse. If I accidentally swap state and city my program will still compile as both parameters are Strings, but it will probably fail at an unexpected time later.
2. The arbitrary values used to construct the Address do not reveal intention. Why “123 Main St”? Why “IL”? Could I change that to be any state? Which values are effecting the outcome of each test and which are completely arbitrary?
3. Optional parameters. lineTwo seems to be optional because of the empty String. Should we overload the constructor instead? Provide a setter?

And customizing the Address fields for each test:

1. Prefer immutable state. The setState method makes Address mutable. Before that, we had a nice, happy immutable object, as you can see by the presence of the final keyword on the other instance fields.
Because we were using the same Address object in many tests and we needed a different value for only one field, we added a setter instead of calling the constructor again. On the upside though, at least this test reveals its intention - that this test only cares about the state field.
2. Keep test-only code out of production code. It’s very likely that setState was added for this one test, and is not called by any production code. This is a smell that should be avoided.

## 2) Introducing a Builder

First, we attempt to give Address it’s immutability back and avoid adding telescoping constructors by introducing a Builder. The Builder allows us to separate the steps for constructing an object from the final representation of it.

Looking good Needs improvement

The Builder lets tests construct Address instances without invoking the public constructor, reducing the coupling to it.

The addition of default values to the Builder pulls that arbitrary data out of the tests themselves, which further helps to highlight any tests that need a specific value, and without needing a setter.

Address is immutable. :)

This is yet another class to maintain.

By making the Builder a separate object, we still need Address's public all-args constructor. Any other test could easily bypass the builder. And, because the constructor is still there, all the problems from before remain.

Additionally, our Builder actually has two responsibilities. First is how to construct the Address, as in, which parameters to pass into the constructor. Second, what to construct it with, because the Builder has default values.

Part II will look at moving the Builder into a static inner class to fix the constructor with too many parameters issue.