Create test objects using Factory Methods or Object Mother pattern

Mariusz Wojcik

One of the nightmares in unit testing is creating instances of tested objects. While our tested object grows, very quickly the code repetition appears in the test fixture. It is very important to keep unit test code clean, so the changes to tested object can be easily introduced. It’s also important for unit test code to be easy to read. Very often you can find following code in the test fixture:

[TestMethod]
public void AddressIsEqualToItself()
{
    Address address = new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA");
 
    Assert.AreEqual(address, address);
}
 
[TestMethod]
public void AddressesAreEqualWhenAllFieldsAreEqual()
{
    Address address = new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA");
 
    Assert.AreEqual(new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA"), address);
 
    Assert.AreNotEqual(new Address("United States", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA"), address);
    Assert.AreNotEqual(new Address("United Kingdom", "Middlesex", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA"), address);
}
 
// more tests requiring instances of Address

The problem with this approach is, that if Address class will have to change the definition of constructor all those test will also require a change. This can be solved by using Factory Method pattern:

private Address CreateAddress(string country, string county, string city, string street, string houseName, string postCode)
{
    return new Address(country, county, city, street, houseName, postCode);
}
 
private Address CreateAddressInUK(string county = "Surrey", string city = "Guildford", string street = "St. George Av.", string houseName = "Elliot House", string postCode = "GU3 1DA")
{
    return this.CreateAddress("United Kingdom", county, city, street, houseName, postCode);
}
 
private Address CreateAddressInUS(string county = "Surrey", string city = "Guildford", string street = "St. George Av.", string houseName = "Elliot House", string postCode = "GU3 1DA")
{
    return this.CreateAddress("United States", county, city, street, houseName, postCode);
}
 
[TestMethod]
public void AddressesAreNotEqualWhenCountriesDiffer()
{
    Address address = this.CreateAddressInUK();
 
    Assert.AreNotEqual(this.CreateAddressInUS(), address);
}

In the above example there are three Factory Methods. One generic allowing to create any valid address, and two specialised to create addresses in the UK or US. The specialised methods are defined with optional parameters which simplifies tests even more.

To go even further with this approach, the Object Mother pattern can be applied by creating a class containing specialised factory methods, such as: CreateAddressInGuildfordUK, CreateAddressInLondonUK, CreateAddressInNY, etc.:

internal static class AddressMother
{
    public static Address CreateAddress(string country, string county, string city, string street, string houseName, string postCode)
    {
        return new Address(country, county, city, street, houseName, postCode);
    }
 
    public static Address CreateAddressInGuildfordUK(string street = "St. George Av.", string houseName = "Elliot House", string postCode = "GU3 1DA")
    {
        return CreateAddress("United Kingdom", "Surrey", "Guildford", street, houseName, postCode);
    }
 
    // ...
}

Using Object Mother class is very useful when there is more than one test which requires to create instances of the object, like the test for Customer class which aggregates an Address.

References: