Simplify Unit Testing With Dependency Injection

After you read a bit about dependency injection you might say “So what? There isn’t much of a practical gain” and an the surface I actually agree with you, I mean how many instances are there where we really need to be able to create infinate class permutation without using subclassing? I believe the place where you are going to see dependency injection score major points is with your unit testing. The main reason is that you can provide mock implementations of all the dependencies and eliminate any vairance in their behaviour from the class you are testing.

For example, continuing from my previous post: with traditional composition we could test the Car class like this:

public class CarTest extends TestCase {

 public void testCar() throws Exception {
 Car c = new Car();
 assertEquals(.....);
 }

}

but the behaviour of the instance of car is really coupled to the behaviour of the AutomaticTransmission and GasEngine classes. If something breaks in the AutomaticTransmission class, more than likely our AutomaticTransmissionTest and CarTest cases will fail. This is slightly misleading because there isn’t really a problem with the Car class, and yet its test is failing because of the coupled behaviour to the AutomaticTransmission class. Using the dependency injection version of the class allows us to do something very different.

public class CarTest extends TestCase {

 private static class MockTransmission implements Transmission {
   ...
 }

 private static class MockEngine implements Engine {
   ...
 }

 public void testCar() throws Exception {
 Car c = new Car(new MockTransmission(), new MockEngine());
 assertEquals(.....);
 }

}

Now the Car we are testing has no dependencies outside of our testcase, this allows us to tightly control what we are putting under test and allow us to focus our effort on testing the single class rather than any extra behaviour that comes from the subcomponenets. In this scenerio if something breaks in the AutomaticTransmission class only the AutomaticTransmissionTest will fail because CarTest no longer has a dependency on AutomaticTransmission allowing them to operate (and fail) independently of one another.