Main menu:

Site search

Categories

July 2010
M T W T F S S
« Jan    
 1234
567891011
12131415161718
19202122232425
262728293031  

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