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)));
September 30, 2016 at 6:51 pm |
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.