Blog

Test Data Builders Refined

April 26, 2008

Last year, I blogged about Test Data Builders here and here. I still use them heavily in my unit tests for creating objects with test data. Heck, I also use this pattern for fluent interfaces in production code. Here is a simple example of this approach:

public class CustomerBuilder
{
    public String _firstName = "Homer";
    public String _lastName = "Simpson";
        
    public CustomerBuilder WithFirstName(String firstName)
    {
        _firstName = firstName;
        return this;    
    }

    public CustomerBuilder WithLastName(String lastName)
    {
        _lastName = lastName;
        return this;
    }
        
    public Customer Build()
    {
        return new Customer(_firstName, _lastName);    
    }
}

This fluent builder class can then be used this way:

Customer customer = new CustomerBuilder()
    .WithFirstName("Homer")
    .WithLastName("Simpson")
    .Build();

A while ago, Greg Young started a series of blog posts on DDDD (Distributed Domain-Driven Design), which I can highly recommend. Make sure to catch up now you still can because I think that he has a lot of stuff coming up, which I'm really looking forward to.

Anyhow, Greg had a couple of posts on fluent builders, which you can read here, here and here. I noticed an interesting approach in the way that the target object is built. Here is an example of this approach:

public class CustomerBuilder
{
    public String _firstName = "Homer";
    public String _lastName = "Simpson";
        
    public CustomerBuilder WithFirstName(String firstName)
    {
        _firstName = firstName;
        return this;    
    }

    public CustomerBuilder WithLastName(String lastName)
    {
        _lastName = lastName;
        return this;
    }
        
    public Customer Build()
    {
        return new Customer(_firstName, _lastName);    
    }

    public static implicit operator Customer(
        CustomerBuilder builder) 
    {  
        return builder.Build()    
    } 
}

which results in the following usage:

Customer customer = new CustomerBuilder()
    .WithFirstName("Homer")
    .WithLastName("Simpson");

Adding an implicit cast operator to the builder class makes that its no longer required to explicitly call the Build method. I keep the Build method around for backwards-compatibility reasons or in case I ever need it again (violating YAGNI in the process, I know, I know). I find that adding the implicit cast operator adds to the readability of the fluent interface, don't you agree?

If you and your team want to learn more about how to write maintainable unit tests and get the most out of TDD practices, make sure to have look at our trainings and workshops or check out the books section. Feel free to reach out at infonull@nullprincipal-itnull.be.

Profile picture of Jan Van Ryswyck

Jan Van Ryswyck

Thank you for visiting my blog. I’m a professional software developer since Y2K. A blogger since Y2K+5. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Past organizer of the European Virtual ALT.NET meetings. Thinking and learning about all kinds of technologies since forever.

Comments

About

Thank you for visiting my website. I’m a professional software developer since Y2K. A blogger since Y2K+5. Author of Writing Maintainable Unit Tests. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Thinking and learning about all kinds of technologies since forever.

Contact information

(+32) 496 38 00 82

infonull@nullprincipal-itnull.be