Jag började uppifrån-och-ned, som är tanken i BDD. Då blev jag satt i följande situation:
1. Indata till NAutoDoc är en sökväg till en mapp som ska scannas.
2. Utdata från NAutoDoc är en HTML-fil.
Försökte mig på detta i kod:
public interface IFileWriter { void WriteFile(string path, string content); } [Test] public void NoInputFilesDoesNotProduceAnOutputFile() { // Dependency DynamicMock fileWriter = new DynamicMock(typeof(IFileWriter)); fileWriter.ExpectNoCall("WriteFile"); // SUT (subject under test) TestDocGenerator gen = new TestDockGenerator( (IFileWriter)fileWriter.MockInstance, "somepath"); gen.GenerateReport("report.html"); fileWriter.Verify(); }
Men här låser det sig i min hjärna: hur specificerar jag att ”somepath” inte innehåller några filer? Jag tänkte mig att TestDocGenerator skulle instansiera någon ”filescanner”-klass mha. ”somepath” internt, och använda denna för att rekursivt söka igenom en sökväg.
Satt fast med denna problematik nästan en hel dag innan jag kom på mitt tankefel: ”somepath” är ett beroende! Det borde alltså mockas, inte instansieras internt i TestDocGenerator!
Försök två blir alltså:
public interface IFileList { List<string> GetFiles(); } public interface IFileWriter { void WriteFile(string path, string content); } [Test] public void NoInputFilesDoesNotProduceAnOutputFile() { // Dependency DynamicMock fileList = new DynamicMock(typeof(IFileList)); fileList.ExpectAndReturn("WriteFile", new List<string>()); DynamicMock fileWriter = new DynamicMock(typeof(IFileWriter)); fileWriter.ExpectNoCall("WriteFile"); // SUT (subject under test) TestDocGenerator gen = new TestDockGenerator( (IFileList)fileList.MockInstance, (IFileWriter)fileWriter.MockInstance); gen.GenerateReport("report.html"); fileList.Verify(); fileWriter.Verify(); }
Slutsats: att instansiera grejer i konstruktor eller annanstans verkar inte vara BDD-vänligt! Det är detta Michael Feathers kallar ett ”internt beroende” i sin bibel ”Working Efficiently With Legacy Code” om jag minns rätt. Det är ett hälsotecken; BDD tvingar fram renare kod.
Läs även andra bloggares åsikter om bdd, nautodoc, programmering, tdd