Java, Mockito and ArgumentCaptor

I knew that day would come at some point. I am programming in Java. One thing that took me longer that I think it should was to figure out how to use Mockito‘s ArgumentCaptor to verify arguments with which methods are called. In this post I share some code snippets that do that, for my reference and hopefully to help other Java beginners.

Suppose we have a class called Swapper that processes some information in form of byte arrays (let’s call them packets).  The class has a method (called swap in the example) that does some processing on the packets. Some of the packets are discarded and some are passed on to the next object (called processor) in the chain of processing. Effectively, the output of the swap method is the argument with which the method process of the processor object is called.

public class Swapper {
    private Processor nextInChain;
    public Swapper(Processor processor) {
        nextInChain = processor;
    }

    public void swap(byte[] packet) {
        if(packet[0] == ((byte) 0) && packet[1] == ((byte) 0))
          return;
        byte b = packet[0];
        packet[0] = packet[1];
        packet[1] = b;
        nextInChain.process(packet);
    }
}

Now we want to test the functionality of the swap method.
First, we get some imports.


import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

Then we declare a mock of an object of the Processor class.

public class SwapperTest {

    @Test
    public void testSwap() {
        Processor processor = mock(Processor.class);

At this point I thought that before running an experiment exercising the swap method we need to tell Mockito somehow that we are interested in collecting the arguments with which the process method is called. However, it turns out that the way Mockito works is that a mock of an object remembers all interactions with its methods and the trick is to get the information we are interested in after the experiment. So, we run the swap method a couple of times on some inputs.

        Swapper swapper = new Swapper(processor);
        byte[][] packets = { { (byte) 1, (byte) 2 }, 
                             { (byte) 0, (byte) 0 }, 
                             { (byte) 3, (byte) 4 } };
        
        for(byte[] p : packets) swapper.swap(p);

And then we do this (note we expect the process method to be called two times):

        ArgumentCaptor<byte[]> messageCaptor = ArgumentCaptor.forClass(byte[].class);
        verify(processor,times(2)).process(messageCaptor.capture());
        List<byte[]> result = messageCaptor.getAllValues();

Now the result variable contains the arguments with which the method process (of the Processor mock) was called.
We can compare it with the result that we expect.

        byte[][] correct = { { (byte) 2, (byte) 1 },
                             { (byte) 4, (byte) 3 } };
        
        assertEquals(correct.length, result.size());
        for ( int i = 0; i < correct.length; i++ )
            assertTrue(Arrays.equals(correct[i], result.get(i))); 

Advertisements

Tags: ,

One Response to “Java, Mockito and ArgumentCaptor”

  1. michaelok Says:

    AHA! Thank you thank you thank you.Searched far and wide to find an example of array of primitives, and your post had the answer.

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: