AKA ‘replace any static method call with a lamda allowing you to test first’
I’m, like many others, a strong believer of TDD, DRY, Build Only Business and Do The Simplest Thing That Could Possibly Work. However sometimes they don’t seem to co-exist very nicely. Although I’m a pretty good at starting holy-crusades against developers in my team that don’t do Test First they always had this one thing I would give them right: there is no use in creating this kind of code:
This kind of code is needed for stubbing and mocking frameworks like RhinoMock, Moq, EasyMock.NET, … and allow you to isolate your subject under test. Very nice, but you cannot expect your co-developers to wrap every static method call or third party funky API. .NET is full of stuff like HttpContext.Current, Cache, DateTime, System.IO.XXX …
Wrapping these stuff goes directly against the DRY and DTSTTCPW principles and delivers no business value whatsoever to your customer.
Things got even worse as soon as Functional Programming started replacing my traditional strict OO way of thinking, passing around delegates and using the static methods available inside the framework eliminates most Unit Testing frameworks… Let’s see how hard it would be to unit-test this kind of code:
There are no wrappers here around the System.IO.Directory static method invocations here, the only way to fully test this code before writing it would force me to create some kind of ‘temporary’ ‘virtual’ file system and use those directories to test this method or write a full-blown scenario test.
Luckily for me, MS Research is working hard on some unit test tooling called Pex. Pex consist of several tools but the one I needed to write the test before I could write the code above is called “Moles”.
Moles allows you to replace any static method with a custom lambda substitute. To do that you first need to download Pex and install it, next you have to add a .moles file to your unit test project in which you describe the assemblies you want your moles to dig in:
I needed to replace some behavior of System.IO classes so I added the mscorlib in which they reside. Pex generates a wrapper assembly (smells like Interop) and exposes every class and method inside it after prefixing it with M, marking it as a mole.
Now it’s time to reveal the actual unit test:
Notice that the following method calls are replaced using lambda expressions:
- MDirectory.ExistsString => System.IO.Directory.Exists
- MDirectory.GetFilesString => System.IO.Directory.GetFiles
- MFile.DeleteString => System.IO.Directory.Delete
Also notice that the required HostTypeAttribute also plays nicely with NUnit, MBUnit, XUnit…
Let’s now hope that Pex can soon ship together with the VS Quality Tools stack!