Dependency Injection on Testing

Fear of needles, known in medical literature as needle phobia, is the extreme fear of medical procedures involving injections or hypodermic needles.

Wikipedia

Dependency injection solves properly interdependence between components, and improves de design of the implementation making easier maintenance and test-ability. This post is intended to understand dependency injection with a practical case on testing, and an explanation how to implemented with an specific framework on Java(Guice) there are more framework out that can do the same.

What is dependency injection?

If my 5 years old son asks me what is dependency injection, I will explained like this: If I need to go the some point of the city, I open my Uber application, I provide some basic information like: my position and my final destination, Uber will provide me car that will go to my place and will drive me to my final destination. So basically the complexity to find the car is hidden to me, like a client I don’t care about the technical details, I just need the service.

At this point some definitions :

  • Client : Me
  • Injector : Uber
  • Service : the car that will transport me
  • Interfaces : The “contracts” or technical conditions between Uber and the Cars

Dependency injection defines a border between the client and the Service, this is important for cases to provide flexibility to implement another services, the only condition that the new service(s) must be complaints with the contracts or interfaces.

Case #1 : Uber

Car : The service

/**
 * Service : the car that will transport me
 */
public abstract class Car {
    /**
     * Contract
     * @param myCurrentSituation current position of client
     * @param finalDestination final destination of client
     */
    abstract String transport(String myCurrentSituation, 
                              String finalDestination);
}

public class FordFiesta extends Car {
    @Override
    /**
     * Contract
     * @param myCurrentSituation current position of client
     * @param finalDestination final destination of client
     */
    public String transport(String myCurrentSituation, 
                            String finalDestination) {
       return "<FordFiesta> takes the client from " 
              + myCurrentSituation + " to " + finalDestination;
    }
}
public class Tesla extends Car{
    @Override
    /**
     * Contract
     * @param myCurrentSituation current position of client
     * @param finalDestination final destination of client
     */
    public String transport(String myCurrentSituation, 
                            String finalDestination) {
        return "<Tesla> takes the client from " 
               + myCurrentSituation + " to " + finalDestination;
    }
}

Service + Interfaces : Binding

import com.google.inject.AbstractModule;

/**
 * Uber have a several Ford Fiesta available close 
 * to the initial position of the client
 */
public class UberPoolOfFordFiestaCars extends AbstractModule {

    @Override
    protected void configure() {
        bind(Car.class).to(FordFiesta.class);
    }
}

import com.google.inject.AbstractModule;

/**
 * Uber have a several car TESLA available close 
 * to the initial position of the client
 */
public class UberPoolOfTeslaCars extends AbstractModule {

    @Override
    protected void configure() {
        bind(Car.class).to(Tesla.class);
    }
}

The Client using the injector

import com.google.inject.Guice;
import com.google.inject.Injector;
import org.junit.Assert;
import org.junit.Test;

public class CarTest {

    @Test
    public void transport_On_Ford_Fiesta() {
        Injector injector 
        = Guice.createInjector(new UberPoolOfFordFiestaCars());

        Car car = injector.getInstance(FordFiesta.class);
        String output = car.transport("my home in Mechelen", 
                        "Ancienne Belgique in Brussels");

        Assert.assertTrue(output.contains("<FordFiesta> takes 
        the client from my home in Mechelen to Ancienne Belgique in Brussels"));
    }

    @Test
    public void transport_On_Testla() {
        Injector injector 
        = Guice.createInjector(new UberPoolOfTeslaCars());
        
       Car car = injector.getInstance(Tesla.class);
       String output = car.transport("my home in Mechelen", 
                       "Aeroport Zaventem in Brussels");

        Assert.assertTrue(output.contains("<Tesla> takes 
        the client from my home in Mechelen to Aeroport Zaventem in Brussels"));
    }
}

Case #2 : Real case on Testing

One client wants automate an application to calculate different loan-credit scenarios. In some cases the taxes and the business logic could change in function of time. Our automated test are using only the System.Datetime, so the challenge was to change the current time to simulate scenarios running with different times. Dependency Injection was useful to split the complexity to chose the different time providers.

2 thoughts on “Dependency Injection on Testing

  1. With havin so much content do you ever run into any problems of plagorism or
    copyright infringement? My site has a lot of exclusive content I’ve either written myself or outsourced but it seems a lot of it is popping it up all over the web without my authorization. Do you know any methods to
    help reduce content from being ripped off? I’d definitely appreciate it.

    Like

  2. Ich habe gestern mehr als vier Stunden bei Yahoo gesucht, doch ich habe nie einen interessanteren Beitrag wie Ihren hier
    gefunden. Für mich ist er ziemlich bedeutend. Würden mehrere Blogger sinvolle Inhalte wie Sie schreiben würden, wäre
    das Internet viel brauchbarer.

    Like

Leave a reply to guter Buchhandel Cancel reply