Using ArgumentCaptor class

This post explains how to capture arguments passed to mocked methods when testing. Suppose we have classes as shown below


class Class1 {
    private Class2 class2;

    public void method1(int val) {
        val = val * val;
        class2.method2(val);
    }
}

class Class2 {
    private int val;

    public void method2(int val) {
        this.val = val;
    }
}

Now you want to test method, you want to make sure that method1 does the square of val and send it to method2.

If method1 returned a value we could have used that value for testing but in this case we cannot. So we use Mockito’s ArgumentCaptor class as shown below


import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class Class1Test {
    @InjectMocks
    private Class1 class1;

    @Mock
    private Class2 class2;

    @Test
    public void testMethod1() {
        ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
        class1.method1(3);
        Mockito.verify(class2).method2(argument.capture());
        assertEquals(9, argument.getValue().intValue());
    }
}

If you refer the bolded code, according to that ArgumentCaptor class’s capture() method is used to capture the arguments when the stubbed method is executed. We can then get the argument passed by using argument.getValue() as done in the next line.

Leave a Reply