转一篇文章,在选择mocking框架的时候参考一下。
http://blog.eweibel.net/?p=376
A few month ago I played with some mocking frameworks in .Net. There are already some comparisons available (here, here or here). In this blog post I want to show which frameworks are available and which one fits best for agile development.
You could download the source code from github.com.
Software under Test (SUT)
To demonstrate and evaluate all the different mocking framework I had to create a scenario where it is appropriate to use a mocking framework. So I chose an user entity which I want to validate and in a successful case also to persist in a database.
SUT
This is the User entity class which implements the active record pattern. As you see, there are three injection patterns realized, the constructor injection and setter injection for the gateway and the parameter injection for the validator.
Code
The UserGateway class is responsible to persist the entity. In my scenario it is just a dummy, because I don’t want to setup a database for this demo.
Code
The validator is also more or less just a dummy for this demo.
Both interfaces, IUserGateway and IUserValidator, has the same methods, properties as the classes which implement them.
NMock2
One of the first mocking frameworks in .Net which I was looking at was NMock2. Specially thecheat sheet make it really easy to learn this framework.
Code
You could use the AAA-Syntax (Arrange-Act-Assert). Also more extended features like the ordered calls with the using syntax is very nice.
But, there is are also negative points: NMock2 uses “magic strings”. In your Expectations you have to declare the called method with a strings, which makes your tests very brittle when your refactor your code. For example if you have to rename a method, even the compiler could not help you. An other negative point is, that you can only mock interfaces. When you have to mock a class, you have to change your design by adding an interface just for mocking.
NMock3
Recently I discover, that there is already a follower of NMock2 on codeplex: NMock3.
Code
The migration is quite easy: Replace the reference from your test project from the NMock2.dll with a new reference to the NMock3.dll. After that you could use the new approach with the MockFactory and the lambda expressions in your Expectations.
NMock3 introduce type safety and readiness for refactorings combined with the easiness of NMock2. They also keep the tradition of a good cheat sheet.
With NMock3 I couldn’t mock a class (even when I followed the exceptions…"). The creation of stubs should be possible. The project is still a young one and so the documentation isn’t that good as it should be. But NMock3 remain an interesting mocking framework.
Simple.Mocking
When I looked for mocking frameworks I also found this new and not very well known frameworkSimple.Mocking on codeplex. Its also avoid “magic strings” and you could also use the AAA-Syntax. Simple.Mocking has only one committer, Mikael Waltersson.
Code
The ExpectationsScope is used to avoid to call AssertExpectations.IsMetFor for each mock. This construct is special and I’m (currently) not a big fan of it.
With Simple.Mocking you could just mocking interfaces and delegates, you couldn’t mock classes.
Rhino.Mocks
Rhino.Mocks is one of the famous .Net mocking frameworks. As Simple.Mocking there is also only one committer to this framework, Oren Eini (alias Ayende Rahien).
Code
Rhino.Mocks supports two ways to use the framework: the record-replay and the AAA-syntax. My favorite is clearly the AAA-syntax, because there is much less code needed (reduced accidental complexity). Rhino.Mocks uses also Lambda-Expressions to avoid “magic strings”, so refactoring shouldn’t be a problem.
Moq
Moq is another mocking framework which takes advantage of the .Net 3.0 language features like lambda expressions. So Moq doesn’t use “magic strings” and it enables also the AAA-syntax. There are two ways how to create mocks. You could create mocks directly with the Mock class or you could use the MockFactory class. For both scenarios I created a test.
Code
I prefer the MockFactory approach, because you don’t need to verify each mock (its reduce the test code which is a good thing). Be sure, that in this scenario you don’t forget the parameter MockBehavior.Strict which makes your mock objects real mocks. Without this parameter they are more like Stubs, which don’t fail and just return a default value.
But there is a little problem: If you want to mock a class, then all the methods have to be virtual, but Moq has no problem to mock an interface.
Typemock Isolator
Unfortunately Typemock Isolator isn’t free, but you could get a trial to try this great mocking framework. As you could see in the TestPersistWithReflectiveMocking Typemock Isolator could mock classes, also non-virtual methods. Great. It also doesn’t use “magic strings”. But wait, you could not mock interfaces? With the new AAA-syntax it is possible and it looks very nice.
Code
Typemock Isolator also supports the record-replay approach (demonstrated in the TestPersistWithNaturalMocking test method). But as you already know, I prefer the AAA-syntax.
The question about Typemock Isolator is, if it is worth to pay for a mocking framework if there are so much other free opportunities? Typemock Isolator is very powerful and for some companies it is very important to get support and also guarantee that the product will be continued for example ten years. In such a scenario Typemock Isolator would be definitely an option. In reaction of such scenarios, also other providers of mocking frameworks offer commercial support for their frameworks, for example Rhino.Mocks.
The undocumented – NUnit Mocking
It is not very known that there exists also in NUnit a mocking framework. It is possible to mock interfaces and classes if the inherit from MarshalByRefObject.
Code
The mocking framework is easy to use and if you already use NUnit, then you don’t need an additional framework.
As I know, it isn’t official and there is no documentation. You have also to use “magic strings” for methods and the limitation for classes also reduce the benefit.
Conclusion
For a modern mocking framework it is essential that its enable refactoring by not using “magic strings”. It is also essential for me that it allows to use the AAA-syntax. A third essential thing is that it allows you to mock classes. You don’t want to create interface just for mocking, for example for your domain model. Avoid accidental complexity is very important, so you shouldn’t add unnecessary code just for mocking. That doesn’t mean that “design for testability” is wrong, “design for testability” means, that you design your code in a way, that you have the possibility to test your code, for example you avoid huge classes (god object anti-pattern) with a lot of private methods or you avoid creation of instances in methods (unable to use dependency injection).
So, which framework fulfill all the requirements? NMock3, which inherit the easiness of NMock2 combined with the elimination of the “magic strings”? Or Typemock Isolator which also eliminate the “magic strings” and could even mock classes?
For me, there isn’t currently a clear winner visible, maybe Typemock makes the race. But there are frameworks which I would no longer use, as NMock2 or NUnit mocking. They don’t fulfill my requirements clearly. That doesn’t mean they aren’t suitable for your scenarios.
Also to be clear: There are other topics that should be considered: mocking events, Stubs, etc. The list of the mocking frameworks isn’t complete, for example Moles is a framework which could be interesting too.