In this video we’ll be adding Test Data Builders to our test suite. The result will be better unit tests that are maintainable and easy to read.
Part 1: Introduction
Part 2: Getting Started
Part 3: Social Unit Tests
Part 4: Heart Container Implementation
Part 5: Test Data Builders
Part 6: Safe Refactoring
Part 7: Basic Player Health
Part 8: An Event Driven UI
Until now we’ve created all of our test data using the new operator. As a result, each instantiation found in our test code is prone to refactoring.
This is fine for a small set of tests, but will become harder to maintain as our test suite grows. If a domain object changes then each one of its instances will have to change as well.
Unit tests are supposed to make us more efficient in the long run. But instead they’re acting like a ticking time bomb of refactoring. For this reason, we’ll have to find a better way to create data for our tests.
Introducing Test Data Builders
Test Data Builders are factory classes that use the builder pattern to instantiate domain objects.
They provide a flexible interface for creating test data that makes your unit tests easier to read. Check out the example below.
It almost reads like a checklist. It uses an invoice with a receipt that has an address with no postcode. Any developer should be able to look at that test and have an idea of what its doing.
And when it comes time to debugging a failing test, this readability will be worth its weight in gold.
But more importantly, Test Data Builders improve the maintainability of your test suite by decoupling the test data from the test logic. They encapsulate the creation code of your domain objects, leaving it a level removed from your tests.
A domain object that is instantiated n number of times must be refactored n number of times. With Test Data Builders an object can be created hundreds of times while only every needing to be refactored once.
This is what makes Test Data Builders essential to writing better unit tests.
Writing Better Unit Tests
Throughout this video we’ll be preparing our tests for refactoring. Each one of our domain objects will get its own Test Data Builder, and all of the tests will be updated to use them.
The process will be made easier thanks to the guidelines offered on Nat Pryce’s blog (imaged below).
And as a bonus, we’ll be adding a little magic to our Test Data Builders in the form of implicit operators. This magic will allow us to cast each builder to it’s respective domain object so we won’t have to call the Build method.
By the end of the video, our test suite will have improved maintainability and readability.