views:

101

answers:

3

I need to test a method belonging to a service class. This service class has several dependencies in the constructor, some used by this method, some not. If we should not be using a DI container for our unit tests what is the best way to instantiate the service class?

var service = new ServiceClass(new Repository1(), new Repository2(), new ServiceClass2(), etc.);

That's hard to read and seems like a lot of code just to test one method. Things get real messy when some of those dependencies have dependencies of their own.

+2  A: 

http://www.myjavatools.com/cuecards/refactoring.html

Constructor → Factory Method

if you want more than simple construction

David B
+2  A: 

Sometimes (especially if it is testing code) a bit of code reformatting can do the trick. While

var service = new ServiceClass(new Repository1(), new Repository2(), new ServiceClass2());

is definitely hard to read, this:

var service = new ServiceClass(
    new Repository1(), 
    new Repository2(), 
    new ServiceClass2()
);

seems a bit better (at least to me).

Andrew Hare
+2  A: 

You should really look at using a mocking framework to isolate your test from the actual dependent objects. I'm assuming you use C# (from the var keyword), so I'll give an example from RhinoMock.

var respository1 = MockRepository.GenerateMock<Repository1>();
repository1.Expect( r => r.SomeMethod() ).Return( someValue );

var repository2 = MockRepository.GenerateMock<Repository2>();
repository2.Expect( r => r.Method2() ).Return( someValue );

 ...

var service = new Service( repository1, repository2, ... );

repository1.VerifyAllExpectations();
repository2.VerifyAllExpectations();

Using this mechanism you can control how the mock object responds to your class under test and you isolate your test code from related dependencies. You can also test that your class under test is interacting properly with the classes that it depends on by verifying that the expectations that you set up have been met (called).

As for the number of parameters in the constructor, consider providing a default constructor that takes no parameters and having public settors for the dependencies. Then you can use the convenience mechanisms in C# 3.0 for defining them.

var service = new Service {
    Repository1 = repository1,
    Repository2 = repository2,
    ...
};
tvanfosson
I see where you are going with this, and actually your post created a "aha" moment for me related to mocking.
mxmissile