I've got some doubts regarding how to provide defaults for dependencies and how to handle tests for them. Let's say I have class as follows:
class MyService {
private AnotherService dependency;
...
}
As this is legacy application there is no dependency injection (even home grown one). So to provide dependecy there are several ways (e.g. constructor, setter). But I'd like to provide default implementation for this dependency, but I'm in doubt how to do it.
I'd do it by having
class MyService {
private AnotherService dependency = new AnotherServiceImpl();
...
}
but then this dependency is always initialized when MyService is being created. For tests I don't want this, as I want to provide mock impl. I think of something like
class MyService {
private AnotherService dependency;
private AnotherService getDependency() {
if(dependency == null) {
dependency = new AnotherService();
}
return dependency
}
setDependency(AnotherService dependency) {
this.dependency = dependency;
}
}
Now, if all depedency calls are done via getDependency() first, dependency is loaded the lazy way I think and I can set my own for test.
I know it is hard to start introducing changes like dependency injection in legacy code which doesn't have it already. E.g. if I provide my dependency in constructor, the problem with dependency instantiation just shifts one level up.
Second question is how to provide dependencies if there is only one implementation right now. I'm using Mockito and its @InjectMocks can inject mock into private field. I wonder if there is a need to expose setDependency or constructor arg dependency and make this one impl with interface? Isn't it overengineering it right now? I don't want to alter my code for tests only.