Unit Testing – Pros and Cons of Common Unit Test Scaffolding Code

tddunit testing

For the project my team and me are working on we often find that we need large pieces of scaffolding code. Creating domain objects with correct values, setting up mocks for repositories, dealing with the cache,… are all things that occur commonly throughout the tests. A lof of times we're working with the same basic objects that are central to our domain (person,…) so lots of tests create instances of these objects for other objects to work on. We have a lot of different solutions using the base domain so this kind of code is often spread across those solutions.

I've been thinking about creating common classes that do a lot of this scaffolding. This would allow us to request a fully instantiated person with everything set up (access via repository, caching…). This removes duplicate code from our individual unit tests but would also mean there is a large amount of code that probably does 'too much' per test (as it would set up a full object and not just the parts required).

Has anyone ever done this? Are there any insights, remarks, thoughts… you can offer that might validate or invalidate this approach?

Best Answer

Creating domain objects with correct values

I use the builder pattern to create domain objects for tests as detailed in the "Growing Object-Oriented Software" book. The builders have static methods that generate default values for common objects with methods for overriding the default values.

User user = UserBuilder.anAdminUser().withEmail("test@example.com").build();

You can combine these to generate more complex objects.

We also use test case class inheritance with commonly used mocks for specific types of unit tests - e.g. mvc controller tests frequently require the same mocks/stubs for request & response objects.