I'm currently trying to improve the testability of a legacy system, written in Java. The most present problem is the presence of “inner” dependencies which cannot be mocked out. The solution to this is pretty simple: Introduce dependency injection.
Unfortunately the code base is pretty large, so it would be a huge effort to introduce dependency injection throughout the whole application, up to the “bootstrapping”. For each class I want to test, I would have to change another hundred (maybe I’m exaggerating a bit here, but it definitely would be a lot) classes, which depend on the changed component.
Now to my question: Would it be ok, to use a two constructors, a default constructor which initialize the instance fields with default values and another one to allow the injection of dependencies? Are there any disadvantages using this approach? It would allow dependency injection for future uses but still doesn’t require the existing code to change (despite the class under test).
Current code (“inner” dependencies):
public class ClassUnderTest {
private ICollaborator collab = new Collaborator();
public void methodToTest() {
//do something
collab.doComplexWork();
//do something
}
}
With default / di constructor:
public class ClassUnderTest {
private ICollaborator collab;
public ClassUnderTest() {
collab = new Collaborator();
}
public ClassUnderTest(ICollaborator collab) {
this.collab = collab;
}
public void methodToTest() {
//do something
collab.doComplexWork();
//do something
}
}