Yet another talk about Test-Driven Development
George Ma @ SEEK LTD
Good evening everyone. Firstly I would like to thank Charles for getting me here talking about TDD stuff. My name is George Ma, from seek.com.au. It is a great honour to talk to you about TDD, one of the fundemental aspects of agile practice here.What is it and why it rocks?
Before we talk about TDD, I would like to know how many of you have some experience of programming? Please raise your hand if you have some...OK, most of you have done some. [TestMethod]
public void Add_When_Add_1_And_2_Should_Return_3()
{
// arrange
var calculation = new Calculation();
// act
var result = calculation.Add(1, 2);
// assert
Assert.AreEqual(3, result);
}
[TestMethod]
public void Add_When_Add_2_And_1_Should_Return_3()
{
// arrange
var calculation = new Calculation();
// act
var result = calculation.Add(2, 1);
// assert
Assert.AreEqual(3, result);
}
[TestMethod]
public void Add_When_Add_1_And_0_Should_Return_1()
{
// arrange
var calculation = new Calculation();
// act
var result = calculation.Add(1, 0);
// assert
Assert.AreEqual(1, result);
}
[TestMethod]
public void Add_When_Add_1_And_Minus_1_Should_Return_0()
{
// arrange
var calculation = new Calculation();
// act
var result = calculation.Add(1, -1);
// assert
Assert.AreEqual(0, result);
}
public class Calculation
{
public int Add(int x, int y)
{
throw new NotImplementedException();
}
}
public class Calculation
{
public int Add(int x, int y)
{
return x + y;
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void DivideBy_When_Denominator_Is_0_Should_Error()
{
// arrange
var calculation = new Calculation();
// act
var result = calculation.DivideBy(1, 0);
}
public interface ICalculation
{
int Add(int x, int y);
int Minus(int x, int y);
int Multiply(int x, int y);
int DivideBy(int x, int y);
}
[TestMethod]
public void GetResults_When_Pass_In_Plus_Should_Call_Add()
{
// arrange
var calculation = Substitute.For<ICalculation>();
calculation.Add(1, 2).Returns(3);
var controller = new Controller(calculation);
// act
var result = controller.GetResult("1", "2", "+");
// assert
calculation.Received(1).Add(1, 2);
Assert.AreEqual(3, result);
}
public class Controller
{
private readonly ICalculation calculation;
public Controller(ICalculation calculation)
{
this.calculation = calculation;
}
public int GetResult(string operand1, string operand2, string op)
{
var op1 = Int32.Parse(operand1);
var op2 = Int32.Parse(operand2);
switch (op)
{
case "+":
return calculation.Add(op1, op2);
case "-":
return calculation.Minus(op1, op2);
case "*":
return calculation.Multiply(op1, op2);
case "/":
return calculation.DivideBy(op1, op2);
default:
throw new ArgumentException("Unrecognised operator");
}
}
}
[TestMethod]
public void Execute()
{
this.Given("Given user types in the first operand <Operand1>")
.And("and user types in the second operand <Operand1>")
.When("When user chooses operator <Operator> ")
.Then(_ => ThenTheResultShouldBe__Result__())
.WithExamples(new ExampleTable("Operand1", "Operand2", "Operator", "Result")
{
{"1", "2", "+", 3},
{"2", "1", "+", 3},
{"1", "0", "+", 1},
{"1", "-1", "+", 0}
})
.BDDfy();
}