Unit Testing with Komarro – can implicit be more durable?

Testing a unit of code that doesn’t interact with any other test subjects is pretty straightforward. A set of direct inputs to a method and possibly inner state of the system under test determine how the output that has to be verified.

For example a test of a method exponentiation(int base, int power) could look like this:

@Test
public cubing() {
    // given
    int base = 2;
    int power = 3;

    //when
    long result = exponentiation(2, 3);

    //then
    assertThat(result).isEqualTo(8L);
}

The fun starts, however, when the method under test depends on elements that should not influence the test result. When developing a car engine, you don’t want to evaluate how good the throttle, the car’s on-board computer systems or any other piece of the car works. You are interested in the engine. That is why you’d  set up some testing harness to provide all necessary conditions to ignite the engine and to see how it performs.
A computer engineer in order to emulate all elements it depends on would use so called test doubles. Java developers (and I must admit we are very lucky), were given a set of great tools to do the job. Mockito, a prominent example among many great ones, could be used as follows:

private StatisticsService sut;
private clientRepository clientRepository;

@Setup
public prepareSut() {
    clientRepository = mock(ClientRepository.class);
    sut = new StatisticsService(clientRepository);
}

@Test
public averageAgeCalculatedCorrectly() {
    // given
    when(clientRepository.getAllClients()).thenReturn(asList(personAtAgeOf(15),
            personAtAgeOf(45), personAtAgeOf(90)));

    //when
    double averageAge = sut.getAverageAgeOfClients();

    //then
    assertThat(averageAge).isEqualTo(50.0);
}

Passing indirect inputs to a method under test is possible thanks to Mockito’s when idiom. When‘s basic responsibility is to stub method’s response. But is it all it does? Doesn’t it implicitly verify the exact interaction with its dependency? In terms of car engines, is it important where the fuel comes from when testing a motor?

Komarro tries to answer these questions and to expose some other subtleties of unit testing in Java. This is how the Komarro version of the previous test looks like:

private StatisticsService sut;

@Setup
public prepareSut() {
    sut = instanceForTesting(StatisticsService.class);
}

@Test
public averageAgeCalculatedCorrectly() {
    // given
    List<Client> clients = asList(personAtAgeOf(15), personAtAgeOf(45), personAtAgeOf(90));
    given(new TypeLiteral<List<Client>>() {}).isRequested().thenReturn(clients);

    //when
    double averageAge = sut.getAverageAgeOfClients();

    //then
    assertThat(averageAge).isEqualTo(50.0);
}

Komarro, as opposed to other stubbing utilities, replaces the exact method calls in the set-up phase of a test with implicit by-type indirect input definitions. It simplifies  other fixture set-up activities – mocked dependencies don’t have to be created and injected manually.
It is a fully functional stubbing framework based on Mockito that can be complemented with Mockito’s syntax every time it is needed (e.g. for verification purposes).
Komarro injects and manages the mocks automatically, in a manner that is transparent for the user. It guesses the types of the collaborators based on the application metadata in form of annotations. So if your application uses annotations to perform dependency injections you are ready to go (the installation will be especially easy for the maven users).

For usage examples, installation instructions, API and any other further details see http://code.google.com/p/komarro/.


Advertisements
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: