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

Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

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!

Sunday, January 18, 2009

Testing private methods

I am writing a crossword word search puzzle solver for the purpose of practicing Test Driven Development.  Yep, I am only writing code after first writing a test. 

I started off with a very powerful method named SolveForWord:

   public class PuzzleSolver
{
public PuzzleSolution SolveForWord(string word)
}


Almost instantly, I had the urge to start writing private methods to help parse the puzzle into a private data-structure.   But since I’m doing TDD, I had to think about how to continue.  Since I can’t test private methods, how do I write that code? 



To be honest what I did next was find out how other people do in this situation.  After a bit of googling, I decided to try testing my private methods using reflection.  Then it hit me.  My attempt to test private methods was “test friction” right?  The PuzzleSolver class shouldn’t be doing any parsing!  By experiencing this “test friction” I changed my design. 



   public class PuzzleParser
{
public PuzzleParser(string text)
{
}
}


PuzzleSolver will use PuzzleParser to perform parsing and not actually perform parsing itself. Single Responsibility in action!



Note: I didn’t know how much code to include in my post, so I purposely left out most of it.

Saturday, January 17, 2009

Test Driven Development is design

In Hanselminutes podcast #146, Scott Bellware talked about Test Driven Development being design, which I already sort of knew, but what I got out of the show is how TDD can really make a difference in my coding practices.

By practicing TDD, it's going to bring to light all sorts of "test friction". For example, the harder it is to setup tests, the harder TDD becomes. The difficulty I have in setting up tests my objects is a big reason I don't even attempt to practice TDD. Once I realized this, the idea that "test smell begets design smell begets code smell?" sort of made sense. I've got this horrible test smell staring me in the face and now I really want to do something about it.
How can I reduce test setup friction? Is single responsibility (part of SOLID) the answer? Will Structure Map help?

Scott Bellware finished the podcast with a suggestion to read the book TDD in Microsoft .NET by James Newkirk. I actually already own the book and immediately pulled it off the shelf and am re-reading it. ( I read it 2 years ago before I even knew what unit testing was.)

I'm researching this topic heavily and will post more when I find some answers.