When creating tests (for TDD or BDD), use fluent builders

No, I don’t mean the kind that come around and drink all your coffee / tea. When you are testing your code you often have to initialise various classes beforehand. There are several ways to do this. Consider this simple api that takes in a ‘Booking’ object and returns the cost of the booking.

Where the Booking object is

and the Customer object is

Your test could be set up as follows

(please bear with me on these primitive samples and tests!)

Now this doesn’t look too bad, but what if I add more properties to Customer and Booking or force the use of constructors and specific set methods?

Now my test setup becomes

Oh, not so nice any more. I have polluted my test with superfluous information, I am relying on calling the right methods to initialise properties and I have made the test that bit more obfuscated.

Instead, how about this

Much nicer! It is easy to see what we are testing and how it is set up. There is no unnecessary information here. Also, thanks to the use of a builder, all the code for creating those objects is in a central place so you don’t have to edit all your tests when there is a change in how they should be initialised.

Great!  How do I do it?

It’s really not that difficult and once you have written a few you start to get the hang of it.  For instance here are the builder classes we have used above

The main thing to remember when creating a fluent builder is that your methods return the class itself, that allows you to chain them. Note also the static implicit operator that converts between the builder and the object it is building. Adding that means we can directly use the builder in place of the object being built (ie passing the booking builder into the GetCostOfBooking method.

I mean this blog to be an introduction to fluent builders – you can get much more fancy with them than this and I have written a blog here that shows how to do that.

If you have any questions or want to add your own feedback, please comment below.  We would love to hear from you.

SHARE IT:

Commenting area

  1. Fergal Coffey 7th August 2015 at 8:38 am · · Reply

    Nice article; check out Autofixture which does exactly this without the need for custom builders https://github.com/AutoFixture/AutoFixture

    • Thanks Fergal.
      AutoFixture is excellent although I prefer the specificity that custom builders give you

      var booking = new BookingBuilder()
      .FromFirstDay("2015/08/15")
      .ToLastDay("2015/08/19")
      .ForCustomer(customer)
      .AtCostPerDay(10);

      Darren

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>