Let's say you're writing a Yahtzee game TDD style. You want to test the part of the code that determines whether or not a set of five die rolls is a full house. As far as I know, when doing TDD, you follow these principles:
- Write tests first
- Write the simplest thing possible that works
- Refine and refactor
So an initial test might look something like this:
public void Returns_true_when_roll_is_full_house()
{
FullHouseTester sut = new FullHouseTester();
var actual = sut.IsFullHouse(1, 1, 1, 2, 2);
Assert.IsTrue(actual);
}
When following the "Write the simplest thing possible that works", you should now write the IsFullHouse
method like this:
public bool IsFullHouse(int roll1, int roll2, int roll3, int roll4, int roll5)
{
if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
{
return true;
}
return false;
}
This results in a green test but the implementation is incomplete.
Should you unit test every possible valid combination (both of values and positions) for a full house? That looks like the only way to be absolutely sure that your IsFullHouse
code is completely tested and correct, but it also sounds quite insane to do that.
How would you unit test something like this?
Update
Erik and Kilian point out that using literals in the initial implementation to get a green test might not be the best idea. I'd like to explain why I did that and that explanation does not fit in a comment.
My practical experience with unit testing (especially using a TDD approach) is very limited. I remember watching a recording of Roy Osherove's TDD Masterclass on Tekpub. In one of the episodes he builds a String Calculator TDD style. The full specification of the String Calculator can be found here: http://osherove.com/tdd-kata-1/
He starts with a test like this:
public void Add_with_empty_string_should_return_zero()
{
StringCalculator sut = new StringCalculator();
int result = sut.Add("");
Assert.AreEqual(0, result);
}
This results in this first implementation of the Add
method:
public int Add(string input)
{
return 0;
}
Then this test is added:
public void Add_with_one_number_string_should_return_number()
{
StringCalculator sut = new StringCalculator();
int result = sut.Add("1");
Assert.AreEqual(1, result);
}
And the Add
method is refactored:
public int Add(string input)
{
if (input.Length == 0)
{
return 0;
}
return 1;
}
After each step Roy says "Write the simplest thing that will work".
So I thought I would give this approach a try when trying to do a TDD-style Yahtzee game.
if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)