I have a class Foo that uses another class Bar to do some stuff.
I’m trying to do test driven development, and therefore am writing unit tests for Foo to make sure it calls the appropriate methods on Bar, and for this purpose I’m using dependency injection and mocking Bar (using Rhino Mocks).
E.g. (in C#):
class Foo
{
private IBar bar= null;
public Foo(IBar bar)
{
this.bar= bar;
}
public void DoSomething()
{
bar.DoIt();
}
}
class FooTests
{
...
void DoSomethingCallsBarsDoItMethod()
{
IBar mockBar= MockRepository.GenerateMock<IBar>();
mockBar.Expect(b=>b.DoIt());
Foo foo= new Foo(mockBar);
foo.DoSomething();
mockBar.VerifyAllExpectations();
}
}
This all seems to be fine, but I actually want Bar to be configured with a particular parameter, and was going to have this parameter passed in via Foo’s constructor.
E.g. (in C#):
public Foo(int x)
{
this.bar = new Bar(x);
}
I’m not sure which is the best way to change this to be more easily testable. One options I can think of involves moving the initialization of Bar out of its constructor, e.g.
public Foo (IBar bar, int x)
{
this.bar= bar;
this.bar.Initialize(x);
}
I feel that this is making Bar harder to use though.
I suspect there may be some kind of solution that would involve using an IoC container configured to inject Foo with a mock IBar and also provide access to the created mock for expectation validation, but I feel this would be making Foo unnecessarily complex. I’m only using dependency injection to allow me to mock the dependencies for testing, and so am not using IoC containers at present, just constructing dependencies in a chained constructor call from the default constructors (although I realize this is creating more untested code) e.g.
public Foo() :
this(new Bar())
{
}
Can anyone recommend the best way to test dependent object construction/initialization?
It seems to me that you are letting an implementation detail leak through the API design. IBar shouldn’t know anything about Foo and its requirements.
Implement Bar with Constructor Injection just like you did with Foo. You can now make them share the same instance by supplying it from the outside:
This would require your Foo constructor to look like this:
This allows Foo to deal with any implementation of IBar without letting the the implementation details leak through. Separating
IBarfromxcan be viewed as an implementation of the Interface Segregation Principle.In DI Container terminology,
xcan be viewed as being Singleton-scoped (not to be confused with the Singleton design pattern) because there is only a single instance ofxacross many different components. The instance is shared and it is strictly a lifetime management concern – not an API design concern.Most DI Containers have support for defining a service as a Singleton, but a DI Container is not required. As the above example shows, you can also wire shared services up by hand.
In the cases where you don’t know the value of
xuntil run-time, Abstract Factory is the universal solution.