Jul
04
2008

What Am I Testing

I’ve been spending the better part of two days doing this same process over and over. It doesn’t feel like I’m testing anything of value.

I am not doing it in the C# 3.0ish way, but it is better to explain it that way. I have a class and a façade (MyFacade) that I want to extend and test.

class Foo {
     public string Name { get; set; }
}

class MyFacade {
     public IMyDependency Depend { get; set; }
}

interface IMyDependency {
     IList<Foo> GetAllFoos();
}

So I write my test first like a good boy person should. I know my façade should give me back a list of the Name properties from the Foo objects it knows about.

[TestFixture]
public class MyFacadeTests {
    [Test]
    public void GetFooNames_ReturnsOnlyName() {
        FakeDependancy fake = new FakeDependency();
        MyFacade m = new MyFacade() { Depend = fake };
        Assert.That(m.GetFooNames(), Is.EquivalentTo(fake.FakeFoos.Select(x => x.Name)));
    }
}

I need that FakeDependency, so I go ahead and create that. This would be a like my repository that will allow me to initialize the fake data.
class FakeDependency : IMyDependency {

    // My local fake repository
    public IList<Foo> FakeFoos = new List<Foo>{
                new Foo{ Name="A"},
                new Foo{ Name="B"},
                new Foo{ Name="B"}};

    public IList<Foo> GetAllFoos() {
        return FakeFoos;
    }
}

OK. So now that I have that, I add my GetFooNames stub to MyFacade.

class MyFacade {
    public IMyDependency Depend { get; set; }

    public IList<string> GetFooNames()
    {
        return null;
    }
}

Run my test. It fails. Good. Now to implement that method….uhh I just copy my assert statement:

fake.FakeFoos.Select(x => x.Name)

…replace “fake.FakeFoos” with “Depend.GetAllFoos()” and I get:

class MyFacade {
    public IMyDependency Depend { get; set; }

    public IEnumerable<string> GetFooNames() {
        return Depend.GetAllFoos().Select(x => x.Name);
    }
}

Build it. Run it. It passes. What did I really test since I just copied the assert statement into the implementation body and changed the source? Did I test anything? That my copy code does the same thing in two places? Am I wasting time?
I rolled it around with a friend and decided to take out the select in the assert statement and replace it with a declarative list so it would look like this:

Assert.That(m.GetFooNames(), Is.EquivalentTo(new[]{"A","B","C"}));

That make me feel a little less “copy and pastey”, but now I have to know my fake is setup to give me three letters for the names. Let’s add a little bit to the fake to make it easier to configure. I am hesitant to do this since I don’t want to add code to my test classes, but I think in the end it is more readable than a more raw configuration.
So I added this to my test class:

public FakeDependency With(int i)
{
    FakeFoos.Clear();
    for (int j = 0; j < i; j++)
    {
        FakeFoos.Add(new Foo());
    }
    return this;
}

public FakeDependency Named(string name)
{
    for (int i = 0; i < FakeFoos.Count; i++)
    {
        // We want them to be 1 based and not zero based
        FakeFoos[i].Name = string.Format("{0} {1}", name, i + 1);
    }
    return this;
}

And use it in my test like this:

[Test]
public void GetFooNames_ReturnsOnlyName() {
    FakeDependency fake = new FakeDependency().With(3).Named("Fake");
    MyFacade m = new MyFacade() { Depend = fake };
    Assert.That(m.GetFooNames(), Is.EquivalentTo(new[]{"Fake 1","Fake 2","Fake 3"}));
}

I’m a lot happier with that than copying the same code from the test to the implementation classes.

Written by Mark in: Unit Testing | Tags:

No Comments »

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress | Kredit | TheBuckmaker