public void Blah() {becomes:
doSomething(ClassName.GetInstanceName().GetInstanceVariable().GetAttribute());
}
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.
Haskell gets this for "free" by vigorously enforcing the separation of pure calculations, which operate only on their arguments, from impure statements which interact with things you can't see just by reading the code in front of you.
ReplyDeleteI say free because I tried to learn Haskell but only got as far as appreciating the benefits of purity. I never reached the point of productively harnessing it's capabilities.
They do it by not having objects, and instead have something else. It's remotely like objects but not enough to protect you from a hideous learning curve.