The diary of a .NET Developer, working on an unlaunched startup project. Also, I live and work in Southern Oregon.

Thursday, January 22, 2009

TDD and Private Methods: What an eye opener!

I’m continuing to practice TDD while creating a simple word search solver. I’m giving TDD a shot is because normally I don’t write testable code and find it difficult to create unit tests after getting so far into a project. This leads to little or no unit tests.

In my short time trying TDD, I’ve realized a couple things about my coding style. Although my code always works (ie. it performs the task at hand), it is full of interdependencies. This creates an environment that is pretty much impossible to write unit tests for. Any tests that I do write only cover large parts of the system, but they are not testing small units of my code—so they do not provide much value.

By sticking to TDD I’ve been forced to change this style in a drastic way!

Normally, this how my public facing code would look. The algorithm for SolveForWord would basically be hiding inside some private methods and fields of the PuzzleSolver class.

PuzzleSolver solver = new PuzzleSolver(wordSearchText);
PuzzleSolution solution = solver.SolveForWord(“dog”);
I could only test the method “SoveForWord”, which tells me nothing about how it was implemented.

With TDD, I did things much different. After a bit of “new thinking”, I created a PuzzleParser class that implements parsing and data manipulation, and left the PuzzleSolver class to perform only the solving algorithm. PuzzleSolver gets an instance to PuzzleParser in the constructor. Then I extracted an interface for PuzzleParser:

    public interface IPuzzleParser
{
string GetLetterFromCoordinate(int row, int col);
string GetLettersFromCoordinate(int row, int col, ParseDirection direction);
int MaxCol { get; set; }
int MaxRow { get; set; }
}

This is of course the DependencyInjection pattern, and I finally get why this is so valuable! In this case, I can mock the parser in a test:



            MockRepository mock = new MockRepository();

IPuzzleParser parser = mock.StrictMock<IPuzzleParser>();

PuzzleSolver solver = new PuzzleSolver(parser);


So it's certainly baby steps in the right direction, but mabye I'm starting to see the light!

No comments:

Post a Comment