Main menu:

Site search

Categories

March 2010
M T W T F S S
« Jan    
1234567
891011121314
15161718192021
22232425262728
293031  

Tags

Blogroll

Using Builders in Tests

An annoying part of writing a test is the amount of setup an object can need in order to use it within the test. 

public void ShouldCalculateVolume()
{
	Box box = new Box();
	box.Type = Cardboard;
	box.Width = 10;
	box.Height = 20;
	box.Depth = 40;
	Assert.AreEqual(8000, box.Volume)
}

However, there is a solution: builders. Builders help by allowing you to only setup the data relevant to the test, but still having a fully formed object. By chaining your methods, you also reduce the amount of lines required for setup. Another advantage of using builders is obvious when you start to refactor the object: instead of fixing all your tests because you have added a new mandatory field, you only have one point of failure.

public void ShouldCalculateVolume()
{
	Box box = new BoxBuilder().Width(10).Height(20).Depth(40).Build();
	Assert.AreEqual(8000, box.Volume)
}

public class BoxBuilder
{
	int width = 1;
	int height = 1;
	int depth = 1;
	Material type = Cardboard;

	public Box Build()
	{
		Box box = new Box();
		box.Type = Cardboard;
		box.Width = width;
		box.Height = height;
		box.Depth = depth;
		return box;
	}

	public BoxBuilder Width(width)
	{
		this.width = width;
		return this;
	}
	public BoxBuilder Height(height)
	{
		this.height = height;
		return this;
	}
	public BoxBuilder Depth(depth)
	{
		this.depth = depth;
		return this;
	}
}

Of course, my example is quite trivial and the only obvious benefit is that I put all the property definitions on one line. However, when you start adding other more complex objects (like perhaps those within your aggregate), then you have some powerful testing techniques under your fingers.

Comments

Comment from Pat
Time November 19, 2008 at 8:26 am

I definitely like builders (actually, builder + factory here as most builders normally don’t have defaults) for the reasons you mention.

However, I think it’s more important to point out their value in highlighting what is different about this particular test.

Comment from Mark
Time November 19, 2008 at 11:52 am

You can reduce a bit of boilerplate using a hashmap of field name to field values and pushing them into the object with reflection.

Write a comment