The mantra of TDD goes “Red, Green, Refactor!” That is, you write a test that fails, you make that test pass, and then you refactor to remove duplication and other code smells.
It’s a good idea to keep in mind where in the TDD groove one is at each moment, even if the time spent in each phase may be as short as a few seconds. When one has a failing test, one shouldn’t be refactoring. When one is refactoring, one shouldn’t write new tests that fail. This is a good rule to follow, and I always try to follow it meticulously.
One refactoring always make me kind of lost when trying to adhere to the above rule: Extract Class. Most refactorings only touch the internals of whatever class is currently being TDD’ed. Refactorings don’t change the behavior of a class, and should therefore not need new tests. In one sense this is true for Extract Class as well; it does not change the behavior of the original class. But it does, however, create a new class, with it’s own behavior that needs to be tested.
The common way to handle this seems to be to just let things be and let the tests that assert the behavior of the original class indirectly test the behavior of the extracted class. In most scenarios this is probably ok, but the fact that you cannot remove the dependency from the original class to the extracted class without losing test coverage kind of bugs me.
After some discussions about this on the TDD list some embryos for best practices emerged.
- When one is using the original tests to assert the behavior of the extracted class, it may be a good thing to make the extracted class a nested private class of the original class. At least as an intermediate step. This tells the world that the marriage between the two behaviors has not been completely dissolved yet.
- As part of extracting the class, take time to consider what the behavior is that one is pulling out of the original class. Then, look for tests that cover that behavior, and see if it is possible to pull those tests out to a different test fixture. Perhaps after some further refactoring of the tests. Initially, let the new test fixture test the original class. After the refactoring is performed, let it test the extracted class.
- Carl Manaster suggested that triangulation be used when extracting the class. I think this can be used as part of refactoring the tests as well.



Leave a Reply
Recent Blog Entries
