Is there a way to use mocks or fakes in your unit tests without having to use dependency injection or inversion or control?
I found this syntax can be used with TypeMock Isolator (http://learn.typemock.com/). It is a comercial product though, so I was hoping that other frameworks (such as RhinoMocks) would be introducing such syntax at some stage.
/// Can mock objects WITHOUT DEPENDENCY INJECTION.
var hand = Isolate.Fake.Instance<Hand>();
var mouth = Isolate.Fake.Instance<Mouth>();
Isolate.Swap.NextInstance<Hand>().With(hand);
Isolate.Swap.NextInstance<Mouth>().With(mouth);
...
//notice we're not passing the mocked objects in.
var brain = new Brain();
brain.TouchIron(iron);
...
This is very attractive to me this type of syntax, it all happens automatically. We can create a brain there with no required dependencies being passed in and the mocking framework will substitute the dependencies automatically for the mock objects. Any body seen this type of thing anywhere else?
The brain class constructor looks like this now using the above syntax,
public Brain()
{
_hand = new Hand();
_mouth = new Mouth();
}
Whereas the dependency injection example would look like this,
public Brain(IHand hand, IMouth mouth)
{
_hand = hand;
_mouth = mouth;
}
Thanks.
Dependency injection is a way to scale the mocking approach. If a lot of use cases are relying on the interaction you'd like to mock, then it makes sense to invest in dependency injection. Systems that lend themselves easily to dependency injection: An authentication/authorization service.
Only use a mock (or test double) “when testing things that cross the dependency inversion boundaries of the system” (per Bob Martin). If I truly need a test double, I go to the highest level in the class hierarchy diagram above that will get the job done. In other words, don't use a mock if a spy will do.
Mockito tries to inject mocked dependencies using one of the three approaches, in the specified order. Constructor Based Injection - when there is a constructor defined for the class, Mockito tries to inject dependencies using the biggest constructor.
Because of this, you can only mock interfaces, or virtual methods on concrete or abstract classes. Additionally, if you're mocking a concrete class, you almost always need to provide a parameterless constructor so that the mocking framework knows how to instantiate the class.
If you have a choice, you should almost always expose a constructor to allow dependencies to be injected. You could still keep the convenience constructor (though some would argue that you shouldn't):
public Brain() : this(new Hand(), new Mouth()) { }
That said, in addition to Isolator you could check out the latest builds of Pex (0.17), which include moles that provide a mechanism similar to Isolator's Swap
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With