views:

316

answers:

2

Okay so I have been trying to get into IoC lately. However, I keep running into one hurdle - that is the fact that I love using mock objects.

They are quick and painless to setup.

However, if I use IoC all over the place in my code then it forces me to create test implementations (and configurations) of my objects instead of using mock objects (ie. using moq).

The end result is that I end up with enormous configuration files for testing.

In addition there are many scenarios in testing where I require different behaviors out of my classes on a test-to-test basis. With moq objects this is extremely easy. How would you do something similar with IoC?

Any help would be much appreciated.

Thanks,
Mike

+3  A: 

IoC should make using mock objects easier, not harder.

Several IoC Container frameworks will allow you to define pre-existing objects to inject; with Moq you'd just set it up for myMockObject.Object.

EDIT: Example of configuring Unity with a mock:

var mockService = new Mock<IMyService>();
container.RegisterInstance<IMyService>(mockService.Object);

As an alternative, you can just pass the mock object into the constructor of the class under test (for constructor injection) and bypass the IoC container entirely in your unit tests.

EDIT: Josh's answer is a good example of the alternative. I would generally go with his solution rather than reconfiguring the container.

TrueWill
Nice showing how to use the IoC for testing. We ended up having to roll our own IoC for use with WCSF out of a web context. It was surprisingly easy to do and ended up being an excellent exercise in understanding the Dependency Injection and IoC patterns.
Josh
+3  A: 

I love IoC, and I love me some Mock Objects...

There is no conflict with these two. If you are doing any kind of Dependency Injection then you should simply have to create mock objects using your favorite mocking framework and then pass them into your SUT.

[Test]
public void AnAwesomeTest()
{
    IDependencyOne d1 = MyMocker.Create<IDependencyOne>();
    IDependencyTwo d2 = MyMocker.Create<IDependencyTwo>();

    //Constructor injection
    SUT sut = new SUT(d1);

    //Property Injection
    sut.DependantProperty = d2;

    //Do some stuff and Assert
}
Josh
+1. Note that it would be "new SUT(d1.Object)" with Moq.
TrueWill
Interesting. I am used to RhinoMocks myself... if the syntax doesn't give that away.
Josh
@Josh: One difference is that d1 and d2 would be of type Mock<IDependency...>. Downside is having to do .Object to get at the interface, upside is being able to set expectations on d1 and d2 directly. It's worth comparing/contrasting the libraries; they have different philosophies. I switched from Rhino to Moq some time ago.
TrueWill
I concur with this. If your objects know about the IoC container, that's a bit of a code smell. They should just care about the actual dependencies, not how to get them (which is kind of the point of Dependency Injection).
kyoryu