I’m a relative latecomer to the unit-testing business, and only got to play with Mocking frameworks in my last project.
After testing several frameworks, we opted on RhinoMocks for emulating our classes during testing. This, coupled with a lot of IOC and dependency injection, made our rather complex, distributed system much easier to test. Code everything to interfaces, feed them in via constructors or whatnot, and you can now slip in a fake cache or project-data service and test only the issue at hand.
Now, I still have issues with IOC/Dependency Injection. While it makes testing easier, and enables replacing modules with little hassle, it really complicates the code. One of the nice things about .NET code is how straightforward it is – less plumbing code, metadata separated out to attributes, now we know that the code to our method is much cleaner and more of it actually describes the program logic. Once we start injecting dependencies, things get muddled. Now we have code that uses the various dependencies given to it, but we don’t know where it was created and what actual concrete object it actually is. When everything is interfaces, and the concrete classes themselves may actually be created dynamically with reflection at runtime, there’s no way to read the code and use the Visual Studio code-browsing tools to know what exactly is going on.
I’m not saying we should dump the IOC concepts – they certainly have their uses – but before throwing them into a project we should be aware of their higher learning curve and added complexity, and see whether our project’s scope really needs it. Not every project is a distributed system with dozens of entities talking to each other.
Did I just write all that? All I really wanted to say is that when using RhinoMocks, we were limited in mocking our Configuration Service, since it relied heavily on generic methods to return its data – couldn’t mock generic methods and had to create a concrete “fake” configuration service for use in testing. But now RhinoMocks v3 has been released, with support for mocking generic methods. I am no longer part of that project, but the guys down there say they’ve been busy pushing the new feature into their unit tests. Congrats, Ayende! This is one tool I’ll be taking with me to new projects.