При выполнении TDD и написании модульного теста, как можно сопротивляться желанию «обмануть» при написании первой итерации кода «реализации», который вы тестируете?
Например:
давайте мне нужно вычислить факториал числа. Я начинаю с модульного теста (используя MSTest) что-то вроде:
[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);
}
}
Я запускаю этот код, и он терпит неудачу, так как CalculateFactorial
метод даже не существует. Итак, я сейчас пишу первую итерацию кода для реализации тестируемого метода, записывая минимальный код, необходимый для прохождения теста.
Дело в том, что я постоянно испытываю желание написать следующее:
public class MyMath
{
public long CalculateFactorial(long input)
{
return 120;
}
}
Технически, это правильно, потому что это действительно минимальный код, необходимый для того, чтобы выполнить этот конкретный тестовый проход («зеленый»), хотя это явно «обман», так как он даже не пытается выполнять функцию вычисления факториала. Конечно, теперь часть рефакторинга становится упражнением в «написании правильной функциональности», а не настоящим рефакторингом реализации. Очевидно, что добавление дополнительных тестов с другими параметрами завершится неудачно и вызовет рефакторинг, но вы должны начать с этого одного теста.
Итак, мой вопрос: как вы получаете такой баланс между «написанием минимального кода для прохождения теста», сохраняя при этом его работоспособность и в духе того, чего вы на самом деле пытаетесь достичь?