Tuesday, September 8, 2009

Trainwreck Removal

If your test has a trainwreck in it, DO NOT start building the object chain in your setup so that the trainwreck will execute in your test. That will take forever, and the payoff is next to zilch. Instead, extract the trainwreck expression to a private virtual method you can override:
    public void Blah() {
doSomething(ClassName.GetInstanceName().GetInstanceVariable().GetAttribute());
}
becomes:
   public void Blah() {
doSomething(GetAttribute());
}

protected virtual string GetAttribute() {
return ClassName.GetInstanceName().GetInstanceVariable().GetAttribute();
}

It allows you to override "GetAttribute" in your tests, with something as simple as :
   protected override string GetAttribute{ return "okay"; }

Astute readers will realize that this is the Law of Demeter at work.

Advanced students may note that the public method is in the wrong class now. It doesn't use any local methods or variables, indicating very low cohesion. Time to push it one class deeper in the chain and then reevaluate it to see if parts of the expression need to be pushed further down.

This trick will take you from having to test "in context" with tons of object-chain construction to a new situation where testing is absurdly simple. Use trainwreck removal for all complex indirect accesses including singletons.