How to use Mockito ArgumentCaptor

In this post, I am going to explain how we can use ArgumentCaptor to test out an internal object which is getting passed to some other class.

Consider that you have a Main class which has a method called “populateAndSavePersonData” which is used to construct the Person details(Person Object) and calls the “savePersonData” method from Dao class to populate the data into DB.  Now you want to test out the Person object and its values since it’s not getting returned from this class. So we have to either update the class to return the person object or we can use ArgumentCaptor to capture that object.

Refer the below example to know how we can do that.

Person.java


import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import java.io.Serializable;


public class Person implements Serializable {

    private String firstName;

    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public boolean equals(Object o) {
        return EqualsBuilder.reflectionEquals(this, o);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

}

Main.java and Dao.java


public class Main {

    private Dao dao;
    public Main(Dao dao){
        this.dao = dao;
    }
    public void populateAndSavePersonData(String firstName, String lastName) {

        Person person = new Person();
        person.setFirstName(firstName);
        person.setLastName(lastName);
        dao.savePersonData(person);
    }

    public class Dao {

        public void savePersonData(Person person) {
            // Code to save the data into DB
        }
    }
}

MainTest.java
In our test method, We have to create an ArgumentCaptor object and pass the appropriate object which you want to capture(Person). Then you have to call the actual method with the appropriate arguments. After that call “verify” method on Mockito object and pass the dao object and call the appropriate method(“savePersonData”) which gets called in the “populateAndSavePersonData” method. Finally, we have to get the value from ArgumentCaptor and check the value in it.


import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

public class MainTest {

    @Test
    public void populateAndSavePersonData(){
        Main.Dao dao = Mockito.mock(Main.Dao.class);
        Main main = new Main(dao);
        ArgumentCaptor personArgumentCaptor = ArgumentCaptor.forClass(Person.class);
        main.populateAndSavePersonData("Bala","Samy");
        Mockito.verify(dao).savePersonData(personArgumentCaptor.capture());
        Person person = personArgumentCaptor.getValue();
        assertEquals("Bala",person.getFirstName());
        assertEquals("Samy",person.getLastName());
        System.out.println(person);
    }
}

 

Advertisements

HK2 Dependency Injection – Using Iterable provider

HK2 is a light weight, dynamic dependency injection framework. If you don’t want to rely on spring framework for managing the dependencies then you can use this.

In this post, I am going to explain how to use the Iterable provider with an example.

Assume that you have a Jersey REST application and it has an endpoint which is responsible for sending out some details to different systems such as Kafka, Database. There is a class called Emitter which is responsible for emitting the data. There are two classes KafkaProducer which produce the data to Kafka and another one DatabaseProducer which writes the data into DB and both these classes implement the MessageProducer interface.

I am not going to give the exact code to be used for doing this. My main motive is to show how we can use Iterable provider here.

MessageProducer.java


public interface MessageProducer {
    public void produce(String message);
}

DBProducer.java
DBProducer class sends out the message to DB


public class DBProducer implements MessageProducer {

    @Override
    public void produce(String message) {
        //Write code to send out the message to DB
        System.out.println("Producing the message to DB");
    }
}

KafkaProducer.java
KafkaProducer class sends out the message to Kafka



public class KafkaProducer implements MessageProducer {

    @Override
    public void produce(String message) {
        //Write code to send out the message to kafka
        System.out.println("Producing the message to Kafka");
    }
}

DependencyBinder.java
DependencyBinder class to be used for binding. Hence you need to pass this class as an init parameter to the Jersey servlet(Parameter name: javax.ws.rs.Application)


import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;

import javax.inject.Singleton;

public class DependencyBinder extends ResourceConfig {

    public DependencyBinder() {
       //the resource class is available in com/resource folder
        packages(true, "com.resource");
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(Emitter.class).to(Emitter.class).in(Singleton.class);
                bind(KafkaProducer.class).to(MessageProducer.class).in(Singleton.class);
                bind(DBProducer.class).to(MessageProducer.class).in(Singleton.class);
            }
        });
    }

 

Finally the Emitter class. This class has to send the message to different systems. So we can’t inject the each class here. We can use IterableProvider to achieve this. So the HK2 framework gets all the classes which implement the interface MessageProducer and injects into this class. In this example, it will return DBProducer and KafkaProducer instances.


import org.glassfish.hk2.api.IterableProvider;

import javax.inject.Inject;

public class Emitter {

    @Inject
    private IterableProvider messageProducers;

    public void emitMessage() {

        // Write code to prepare the message
        String message = "Its a new message";
        for (MessageProducer messageProducer : messageProducers) {
            messageProducer.produce(message);
        }
    }
}