Close

Mockito - Creating Spy Of Real Objects

[Last Updated: Oct 26, 2020]

We can use Mockito.spy() to create spies of real objects. The difference between Mockito.spy() and Mockito.mock() is in case of spy() real methods are called.

Examples

Example Project

package com.logicbig.example;

public class MyCalc {

  public int multiple(int x, int y) {
      return x * y;
  }

  public int add(int x, int y) {
      return x + y;
  }
}

Using Mockito#spy()

package com.logicbig.example;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

public class MyCalcTest {

  @Test
  public void multiplyTest() {
      MyCalc myCalcSpy = Mockito.spy(MyCalc.class);
      int result = myCalcSpy.multiple(3, 2);
      Assert.assertEquals(result, 6);

      MyCalc myCalcMock = Mockito.mock(MyCalc.class);
      int result2 = myCalcMock.multiple(3, 2);
      Assert.assertEquals(result2, 0);
  }
}
D:\mockito-spy-example>mvn test -Dtest="MyCalcTest"
[INFO] Scanning for projects...
[INFO]
[INFO] --------------< com.logicbig.example:mockito-spy-example >--------------
[INFO] Building mockito-spy-example 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mockito-spy-example ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ mockito-spy-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mockito-spy-example ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ mockito-spy-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mockito-spy-example ---

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.logicbig.example.MyCalcTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.434 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.773 s
[INFO] Finished at: 2020-10-26T00:04:15-05:00
[INFO] ------------------------------------------------------------------------

As seen in above example the instance of MyCalc created via Mockito.mock() returns 0 on calling multiply() method, that's because by default a mock's method of return type int returns 0, unless we stub it (tutorial).

Use of thenCallRealMethod() on a mock instance

Instance of an object created via Mockito.mock() can also call real methods if we use when()-thenCallRealMethod().

package com.logicbig.example;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

public class MyCalcTest2 {

  @Test
  public void multiplyTest() {
      MyCalc myCalcMock = Mockito.mock(MyCalc.class);
      Mockito.when(myCalcMock.multiple(3, 2)).thenCallRealMethod();
      int result2 = myCalcMock.multiple(3, 2);
      Assert.assertEquals(result2, 6);
  }
}
D:\mockito-spy-example>mvn test -Dtest="MyCalcTest2"
[INFO] Scanning for projects...
[INFO]
[INFO] --------------< com.logicbig.example:mockito-spy-example >--------------
[INFO] Building mockito-spy-example 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mockito-spy-example ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ mockito-spy-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mockito-spy-example ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ mockito-spy-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mockito-spy-example ---

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.logicbig.example.MyCalcTest2
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.426 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.761 s
[INFO] Finished at: 2020-10-26T00:19:36-05:00
[INFO] ------------------------------------------------------------------------

Subbing spies' methods

The spy instances call real methods unless we stub the methods.

package com.logicbig.example;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

public class MyCalcTest3 {

  @Test
  public void multiplyTest() {
      MyCalc myCalcSpy = Mockito.spy(MyCalc.class);
      Mockito.when(myCalcSpy.add(3, 2)).thenReturn(100);

      int result = myCalcSpy.multiple(3, 2);
      Assert.assertEquals(result, 6);

      int result2 = myCalcSpy.add(3, 2);
      Assert.assertEquals(result2, 100);
  }
}
D:\mockito-spy-example>mvn test -Dtest="MyCalcTest3"
[INFO] Scanning for projects...
[INFO]
[INFO] --------------< com.logicbig.example:mockito-spy-example >--------------
[INFO] Building mockito-spy-example 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mockito-spy-example ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ mockito-spy-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mockito-spy-example ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ mockito-spy-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mockito-spy-example ---

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.logicbig.example.MyCalcTest3
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.443 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.830 s
[INFO] Finished at: 2020-10-26T00:24:46-05:00
[INFO] ------------------------------------------------------------------------

Example Project

Dependencies and Technologies Used:

  • mockito-core 3.5.15: Mockito mock objects library core API and implementation.
  • junit 4.13: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • JDK 8
  • Maven 3.5.4

Mockito.spy() Example Select All Download
  • mockito-spy-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
      • test
        • java
          • com
            • logicbig
              • example
                • MyCalcTest.java

    See Also