Quando si fa TDD e si scrive un test di unità, come si può resistere all'impulso di "imbrogliare" quando si scrive la prima iterazione del codice di "implementazione" che si sta testando?
Ad esempio:
Dobbiamo calcolare il fattoriale di un numero. Comincio con un test unitario (usando MSTest) qualcosa come:
[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);
}
}
Eseguo questo codice e fallisce poiché il metodo CalculateFactorial
non esiste nemmeno. Quindi, scrivo ora la prima iterazione del codice per implementare il metodo sotto test, scrivendo minimo codice richiesto per superare il test.
Il fatto è che sono continuamente tentato di scrivere quanto segue:
public class MyMath
{
public long CalculateFactorial(long input)
{
return 120;
}
}
Questo è, tecnicamente, corretto in quanto veramente è il codice minimo richiesto per effettuare quel passaggio di prova specifico (diventa verde), sebbene sia chiaramente un "cheat" dal momento che in realtà nemmeno tenta di eseguire la funzione di calcolo di un fattoriale. Naturalmente, ora la parte del refactoring diventa un esercizio di "scrittura della funzionalità corretta" piuttosto che un vero refactoring dell'implementazione. Ovviamente, l'aggiunta di test aggiuntivi con parametri diversi fallirà e forzerà un refactoring, ma devi iniziare con quel test.
Quindi, la mia domanda è: come si ottiene l'equilibrio tra "scrivere il codice minimo per superare il test" pur continuando a mantenerlo funzionale e nello spirito di ciò che si sta effettivamente cercando di ottenere?