Friday, February 08, 2008

Today I was creating a test data builder for a unit test. I am fairly new to test data builders, on the last project I was on I relied on the ObjectMother pattern which became fairly tedious over time. Both the ObjectMother pattern and the Test Data Builder are Test Helper patterns:

"We define a helper class to hold any Test Utility Methods we want to reuse in several tests." 

If your objects aren't immutable and all you really care about is getting sensible test data without having to repeat yourself, you can use the Rhino Mocks GenerateStub feature to provide sensible test data and deal with invariant test data:

 

[TestFixture]
public class InvoiceTests
{
    [Test]
    public void ShouldCreateInvoiceWithNoPostalCode()
    {
        Invoice invoiceWithNoPostalCode =
                new InvoiceBuilder()
                .WithRecipient(new RecipientBuilder()
                    .WithAddress(new AddressBuilder()
                        .WithNoPostalCode()
                        .Build())
                    .Build())
                .Build();
 
        Assert.AreEqual(string.Empty,
            invoiceWithNoPostalCode.Recipient.Address.PostalCode);
    }
 
 
}
 
public class InvoiceBuilder
{
    private Invoice invoice;
 
    public InvoiceBuilder()
    {
        invoice = MockRepository.GenerateStub<Invoice>();
    }
 
    public InvoiceBuilder WithRecipient(Recipient recipient)
    {
        invoice.Recipient = recipient;
        return this;
    }
 
    public Invoice Build()
    {
        return invoice;
    }
}
 
public class RecipientBuilder
{
    private Recipient recipient;
 
    public RecipientBuilder()
    {
        recipient = MockRepository.GenerateStub<Recipient>();
    }
 
    public RecipientBuilder WithAddress(Address address)
    {
        recipient.Address = address;
        return this;
    }
 
    public Recipient Build()
    {
        return recipient;
    }
}
 
public class AddressBuilder
{
    private Address address;
 
    public AddressBuilder()
    {
        address = MockRepository.GenerateStub<Address>();
    }
 
    public AddressBuilder WithNoPostalCode()
    {
        address.PostalCode = string.Empty;
        return this;
    }
 
    public Address Build()
    {
        return address;
    }
}

Once again be warned that this does not work for immutable objects, I don't recommend making value objects mutable just to implement this pattern so i'm not sure if it actually provides any real value. Maybe if it is combined with a mutable entity and a custom builder for a value object that preserves that value object's immutability. 

If anyone that reads this blog has a way to make Test Data Builders easier I would be glad to hear it.

 

[Currently Listening To: Young Galaxy- Young Galaxy - Wailing Wall]

Friday, February 08, 2008 6:56:17 AM (GMT Standard Time, UTC+00:00)  #    Comments [3]  | 

Theme design by Jelle Druyts

Pick a theme: