I tweeted this yesterday, but confused some folks because, well, because it’s Twitter and using 140 character sound bytes is a terrible way to communicate. I’m working on StoryTeller this morning to finally add a “Delete Test” contextual action to the UI. The architecture for contextual actions and how they plug into StoryTeller are well established and working, so I just need to flesh out how to do the actual test deletion. While working on the “ProjectController” class, I realized that I needed a “DeleteTest()” method on another interface “IProject” as specified in this test:
[TestFixture]
public class when_deleting_a_test : InteractionContext<ProjectController>
{
private Test theTest;
private Suite theSuite;
protected override void beforeEach()
{
theTest = new Test("test 1");
theSuite = new Suite("suite 1");
theSuite.AddTest(theTest);
ClassUnderTest.HandleMessage(new DeleteTestMessage(theTest));
}
[Test]
public void should_invoke_the_inner_project_to_delete_the_test()
{
MockFor<IProject>().DeleteFile(theTest);
}
}
Don’t worry too much about the “InteractionContext / MockFor<T>()” business, that’s just a little test harness superclass I use for auto mocking. I’m working on the ProjectController class here, but I’ve basically made an extension to the IProject interface which will have to be implemented at some point for this whole “Delete Test” process to work. I really don’t want to break my stride on the ProjectController class (because it has other things to do), so I need to drop off some sort of “TODO” to remind myself to come back and implement the “IProject.DeleteFile(Test)” method. I do that by going into the test fixture for the concrete Project class and doing this:
[TestFixture]
public class ProjectTester
{
[Test]
public void delete_a_test_file()
{
Assert.Fail("Do.");
}
}
Now, I can go on and worry about ProjectController without a context switch into the Project file system concerns and be sure that I’ve wrapped up loose ends later because as soon as I start my normal check in dance I’ll get unit test failures gently reminding myself to go back and fill in the blanks. There is a bunch of “throw NotImplementedException” lines all over the real code too, but I’d have to run the UI a bit to run into these. Running the unit test suite turns out to be a faster and more thorough way of finding the little TODO land mines because every unit test runs and gives me a complete picture of what isn’t implemented yet.
Last note, these TODO tests aren’t necessarily a complete specification of the missing implementation, just a TODO that bites back at you to tell you there’s missing work.