When doing TDD and writing a unit test, how does one resist the urge to "cheat" when writing the first iteration of "implementation" code that you're testing?
For example:
Let's I need to calculate the Factorial of a number. I start with a unit test (using MSTest) something like:
[TestClass]
public class CalculateFactorialTests
{
[TestMethod]
public void CalculateFactorial_5_input_returns_120()
{
// Arrange
var myMath = new MyMath();
// Act
long output = myMath.CalculateFactorial(5);
// Assert
Assert.AreEqual(120, output);
}
}
I run this code, and it fails since the CalculateFactorial
method doesn't even exist. So, I now write the first iteration of the code to implement the method under test, writing the minimum code required to pass the test.
The thing is, I'm continually tempted to write the following:
public class MyMath
{
public long CalculateFactorial(long input)
{
return 120;
}
}
This is, technically, correct in that it really is the minimum code required to make that specific test pass (go green), although it's clearly a "cheat" since it really doesn't even attempt to perform the function of calculating a factorial. Of course, now the refactoring part becomes an exercise in "writing the correct functionality" rather than a true refactoring of the implementation. Obviously, adding additional tests with different parameters will fail and force a refactoring, but you have to start with that one test.
So, my question is, how do you get that balance between "writing the minimum code to pass the test" whilst still keeping it functional and in the spirit of what you're actually trying to achieve?