Search Tutorials


Difference between Mock thenCallRealMethod and Spy in Mockito | JavaInUse



Difference between Spy and Mock thenCallRealMethod

Overview

In previous tutorial we saw difference between mock and spy with example. But partial mocking for which spy is used can also be done using mock thenCallRealMethod. So when should we use spy and when the mock thenCallRealMethod.

Lets Begin

We will mock the EmployeePaymentService class defined in the previous tutorial.
package com.javainuse.service;

import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

public class EmployeePaymentServiceTest_MockCallRealMethod {

    private int testWrkingDays = 25;
    private int testSalaryPerDay = 1000;
    private int testSalary = 25000;
    private String empId = "emp100";
	
    //Mock class instance using mock
    @Mock
    private EmployeePaymentService employeePaymentService;

    /**
     * Setup before test.
     */
    @BeforeMethod
    public void beforeMethod() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testGetSalary() {
        //tell mockito to call actual methods instead of mocking
        when(employeePaymentService.getNoOfWorkingDays(anyString())).thenCallRealMethod();
        when(employeePaymentService.getSalaryPerDay(anyString())).thenCallRealMethod();

        //tell mockito to mock the following call
        when(employeePaymentService.processPay(anyString(), anyInt(), anyInt())).thenReturn(testSalary);

        //Actual call as defined above
        int returnedWrkingDays = employeePaymentService.getNoOfWorkingDays(empId);
        Assert.assertEquals(returnedWrkingDays, testWrkingDays);

        //Actual call as defined above
        int returnedSalaryPerDay = employeePaymentService.getSalaryPerDay(empId);
        Assert.assertEquals(returnedSalaryPerDay, testSalaryPerDay);

        //Mock call as defined above
        int returnedSalary = employeePaymentService.processPay(empId, testWrkingDays, testSalaryPerDay);
        Assert.assertEquals(returnedSalary, testSalary);

    }

}

As we can see we called the actual implementation for getNoOfWorkingDays() and getSalaryPerDay() and mocked the processPay() method. So similar partial mocking achieved using spy is also achieved using Mock thenCallRealMethod(). Both can be used interchangeably. However there is major difference between the use of thenCallRealMethod and spy. When we use Mock the actual object instance is not created but bare-bones shell instance of the Class is created to track interactions. Whereas in case of spy we ourselves create the object instance to be used by spy. So using Mockito Spy guarantees that the real methods are called correctly.
For example-
public class EmployeePaymentService {

    EmployeePaymentService(
        final NamedParameterJdbcTemplate namedParameterJdbcTemplate)
        {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
        }
    
    public int getNoOfWorkingDays(String empId)
    {
    	//call some query
    	namedParameterJdbcTemplate.query();
        
    }
}
If for a unit test case we mock the above EmployeePaymentService using Mock as-
@Mock private EmployeePaymentService employeePaymentService;
and later call the actual method getNoOfWorkingDays using thenCallRealMethod as follows-
when(employeePaymentService.getNoOfWorkingDays (anyString())).thenCallRealMethod();
int returnedWrkingDays = employeePaymentService.getNoOfWorkingDays(empId);
We get a java.lang.NullPointerException in the getNoOfWorkingDays method because the namedParameterJdbcTemplate has never been initialized. However if we were using the Mockito Spy this scenario would never arise because we would have ourselves created the EmployeePaymentService using constructor with namedJdbcTemplate.

Download Source Code

Download it - Java Mockito using thenCallRealMethod

Understand Java 8 Method References using Simple Example 
Java - PermGen space vs MetaSpace 
Java 8 Lambda Expression- Hello World Example 
Java 8 Features
Java Miscelleneous Topics
Java Basic Topics
Java- Main Menu