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.