Having outlined the main features of Isolator, I want to now quickly do a simple comparison across the feature-set of the three frameworks, and then discuss how and when I think that Isolator might be a good fit for you. Note that I’m not discussing things like cost of the framework, or level of support and such in the table below – just the actual frameworks themselves.
|Easily discoverable API*|
|Support for AAA|
|Support for record/ replay**|
|Fakes your concretes***|
|Fakes external types****|
|Works with classes not designed for testing|
* A subjective category, but I would argue that Rhino’s API has grown such that it is almost impossible when first starting out to know which part of the API to use and which not to.
** Typemock does support Record/Replay through the RecordManager class; however, AAA seems (to me) to be the primary mechanism for unit testing within the current Isolator framework.
*** Rhino and Moq can both mock your concrete types provided you mark those properties and methods that you wish to fake as virtual
**** Isolator provides limited support for faking .NET types. Some mscorlib types cannot be faked. Other BCL types I found I could only Swap under some circumstances e.g. I could use WhenCalled() on a “real” dataSet to change its behaviour, but was not able to “swap in” a fake dataset using Fake.NextInstance().With().
Key scenarios for using Isolator
There are several situations where I think Isolator is of clear use over and above other unit testing frameworks.
The most obvious situation is where you wish to introduce unit testing into an existing project which was never designed for testability. In such a situation, you have two real options: –
Get a copy of the excellent (if somewhat heavy-going) Working Effectively with Legacy Code and split your classes and dependencies out such that you end up with a testable architecture.
Now, there’s obviously a cost involved in purchasing Isolator, but I would argue that the alternative is to spend time and effort in refactoring code where you currently have no unit tests, which is in itself also a risk, and potentially a large cost as well. Depending on the size of the project, team and future work, you might well find that getting Isolator for your team is actually a cost saving (code smells disclaimer: of course, I’m not saying that using Isolator means don’t obey Single Responsibility Principle etc. )
Projects where you cannot use IoC
Perhaps you have an system architect who does not like IoC. Or you cannot find an IoC framework that you like. Or your system is small enough that you do not need to use an IoC framework, yet you still want testable classes. Either you can manually inject dependencies / resolve them, or again use Isolator to swap out dependencies.
Simplification of class hierarchy
If you have a team that’s relatively junior, you might not wish to introduce concepts such as DI and IoC on them. Don’t laugh – this is a real concern that I have seen in teams before, and you should weigh up the cost of foisting something on them if you feel that they can’t cope with it, or worse still, misuse. Using Isolator means you can test classes that were never written in such a way as to be testable, leading to simplification of class hierarchy (e.g. reduced number of interfaces) and (hopefully) quicker time for developers on your team to get up to speed.
There is obviously a flip-side to this – if you go down this route, you effectively tie the project into using Typemock forever – and whilst I’ve not yet been on a project where I’ve changed mocking framework mid-stream, you never know.
I’ve reviewed the key scenarios when Isolator is going to be the obvious choice for your mocking framework. That’s not to say that it’s the only option (or that it’s not of use in other situations) – but these are the areas that I feel it has a clear advantage over its competitors. In my next post, I’ll discuss the implications of not using IoC and DI with Typemock, as well as concluding the review overall.