Dependency Injection is passing dependency to other objects or framework( dependency injector).
Dependency injection makes testing easier. The injection can be done through constructor.
SomeClass()
has its constructor as following:
public SomeClass() { myObject = Factory.getObject(); }
Problem: If myObject
involves complex tasks such as disk access or network access, it is hard to do unit test on SomeClass()
. Programmers have to mock myObject
and might intercept the factory call.
Alternative solution:
- Passing
myObject
in as an argument to the constructor
public SomeClass (MyClass myObject) { this.myObject = myObject; }
myObject
can be passed directly which makes testing easier.
- One common alternative is defining a do-nothing constructor. Dependency injection can be done through setters. (h/t @MikeVella).
- Martin Fowler documents a third alternative (h/t @MarcDix), where classes explicitly implement an interface for the dependencies programmers wish injected.
It is harder to isolate components in unit testing without dependency injection.
In 2013, when I wrote this answer, this was a major theme on the Google Testing Blog. It remains the biggest advantage to me, as programmers not always need the extra flexibility in their run-time design (for instance, for service locator or similar patterns). Programmers often need to isolate the classes during testing.