Mockito Advanced - Part 2

In part 1 of Mockito tutorial Mockito Basics, we discussed about Mockito basics, which included :

  • Getting your project setup with Mockito
  • Mocking a class
  • Initializing mock object
  • when(...).thenReturn(....)
  • verify(mock).methodCall()

Today we will be discussing more powerful concepts of Mockito.

Spy

spy() method can be used to wrap a real object. Every call, unless specified otherwise is delegated to the object. Difference between a mock and a spy is, when a mock is created a barebone shell instance of a class is to track interaction with it. Whereas, on the other hand Spy will wrap an existing instance.m

Using Spy

Mockito.spy(class<T>) is used create a spy object on a real object.

Stubbing a Spy

While stubbing a Spy, doReturn().when().method() pattern is used.

Example

@RunWith(MockitoJUnitRunner.class)
public class MockitoAdvanced {

    private List<String> userList;
    private List<String> spyList;


    @Before
    public void createSpy(){
        userList = new ArrayList<String>();
        spyList = Mockito.spy(userList);
    }

    @Test
    public void testStubbingSpyObject(){
        Assert.assertEquals(0, spyList.size());

        //Stubbing Spies        
        Mockito.doReturn("Aayush Tuladhar").when(spyList).get(0);

        Assert.assertEquals("Aayush Tuladhar", spyList.get(0));

    }
}

Capturing Arguments using ArgumentCaptor

The ArgumentCaptor class allows to access the arguments of method calls during the verification. Using Argument Captors you can verify argument passed into a mock.

Using ArgumentCaptor.capture(), you can capture the argument and run verification. In below example, arguments passed in to the mock object, “mailService” is captured by the argumentCaptor which is later validated in later phase of the code.

@Test
public void testSendEmailToEmployees(){
    MailProcessor mailProcessor = new MailProcessor(employeeDAO, mailService);
    Mockito.when(employeeDAO.getEmployee(1)).thenReturn(employee);

    //Instantiate Argument Captor to Capture Argument of EmployeeMail Type
    ArgumentCaptor<EmployeeMailDTO> argumentCaptor = ArgumentCaptor.forClass(EmployeeMailDTO.class);

    //Perform Operation
    mailProcessor.sendEmailToEmployee(1);

    //Verify
    Mockito.verify(mailService).sendEmail(argumentCaptor.capture());

    //Verify Correctness
    EmployeeMailDTO employeeMailDTO = argumentCaptor.getValue();
    Assert.assertEquals(employeeMailDTO.getReceipientEmail(), employee.getEmail());
    Assert.assertEquals(employeeMailDTO.getMessage(), "Dear Bob Dylan\n" + "\n"
        + " we are processing your salary amount 1000000. \n" + "\n" + " Regards\n" + "Admin");