Why use a Mocking Framework?
We're currently following the DI model usin开发者_开发知识库g Autofac as an IoC container.
We've recently started looking into mocking frameworks like MOQ and Rhino Mocks. However, we can't seem to justify their usage over just creating Mock implementation classes for each of our interfaces.
Why do this:
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
Instead of this:
class FooMock : IFoo {
bool DoSomething(string input) {
return input == "ping";
}
}
mock = new FooMock();
The latter is more verbose, but seems more flexible and appropriate for complex mocks.
What you have shown in your example is more of a fake/stub than a true mock and it is true that if you only want pre-canned behaviour from a dependent object then often a fake can be a better choice than using a mocking framework.
There is a canonical article by Martin Fowler discussing the fact the Mocks aren't Stubs and I've lifted the following paragraph from it:
The key difference here is how we verify that the order did the right thing in its interaction with the warehouse. With state verification we do this by asserts against the warehouse's state. Mocks use behavior verification, where we instead check to see if the order made the correct calls on the warehouse.
Essentially with mocks you are usually intending to check how your method under test acts upon the dependencies - your mock has expectations and you verify those expectations after the method has run.
You could of course still write your own case by case mocks but using a framework will save you a lot of time, give more readable tests and save on errors in the tests.
That is particulaly true as the expectations you have grow more complex, imagine having a method to test which calls a particular dependant class a variable number of times with varying values depending on input parameters - this would be complex to write a mock for yourself, but trivial using a good mocking framework.
To demonstrate with some code, imagine this PrintOrders method (excuse the silly example):
public void PrintForeignOrders(List<Orders> orders)
{
foreach(var order in orders)
{
if (order.IsForeign)
{
printer.PrintOrder(order.Number, order.Name);
}
}
}
You would probably want to test at least:
- When the list is empty nothing is printed
- When there is a foreign order it is printed
- When there are two orders both are printed (with the right number and name)
With a good mocking framework setting up those tests against the injected printer object is just a matter of a few keystrokes.
Every time you change the interface, then every hand coded mock object (which is in fact a stub) will have to be adjusted in order to be compliant with the new interface.
So having a lot of hand coded stub objects will lead to a lot of maintenance of test code every time you change an interface. The mock created by a mocking framework however will always be compatible with the updated interface.
However, we can't seem to justify their usage over just creating Mock implementation classes for each of our interfaces.
This is exactly what a mocking framework will save you from doing - creating a stub or mock implementation just to be able to test the behavior of your class.
What you are doing is not wrong by any means and if it is feasible to do for your project, by all means stick to it - for many this would seem like a very mundane task though, and this is where using a mocking framework can save you a lot of time, and also avoid bloating of your codebase just for testing and the possibility of additional errors in your mocking implementations.
精彩评论