Guide - 7.10 Migration Mockito 1 to Mockito 2

1 Introduction

With IS 7.10 the Mockito libraries are updated from version 1 to version 2. Since this is an upgrade to a new major version, some migration effort is necessary, when using Mockito for testing.

Using Mockito 2 may help to improve the quality of tests, mainly using by the following points

  • The standard Mockito2 runner (strict runner) detects unused stubs. So test code becomes minimal and its readability is improved
  • The methods anyX() do not accept null values anymore. So code smells can be shown in the tests and the tested code.

1.1 References

2 Major Incompatible Changes

2.1 Get Arguments from InvocationOnMock

Getting arguments for InvocationOnMock does not need the class as an argument anymore. Therefore the following changes are necessary

InvocationOnMock Get Arguments example
-PaymentContext context = invocation.getArgumentAt(0, PaymentContext.class);
-Payable payable = invocation.getArgumentAt(1, Payable.class);
+PaymentContext context = invocation.getArgument(0);
+Payable payable = invocation.getArgument(1);

2.2 Mockito Hamcrest Matchers

The Matchers.argThat method family, which depended on Hamcrest was reworked and moved to a new API. Therefore the following adaptions are necessary:

Mockito Hamcrest Matchers
-import static org.mockito.Mockito.argThat;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;

3 Deprecation

3.1 Mockito JUnit Runner

The Junit runner of Mockito 2 was move to a new package. The old runner will probably be removed in Mockito 3

Annotation - Silent Mockito Runner
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;

3.2 Mockito Matchers

The Mockito Matchers are moved to ArgumentMatchers. The old Matchers will probably be removed in Mockito 3

Annotation - Silent Mockito Runner
-import static org.mockito.Matchers.*;
+import static org.mockito.ArgumentMatchers.*;

4 Mockito Runner

4.1 The Strict Runner

The strict runner is default runner in Mockito 2. This runner detects unused stubs within tests and throws an UnnecessaryStubbingException in these cases.

Annotation - Strict Mockito Runner
import org.mockito.junit.MockitoJUnitRunner
// detect unused stubs
@RunWith(MockitoJUnitRunner.class)

In the code below a UnnecessaryStubbingException in the last line is thrown and this line has to be removed to get the test green.

Strict runner example
//code under test:
...
String result = translator.translate("one")
...

//test:
...
when(translator.translate("one")).thenReturn("jeden"); // <- stubbing realized during code execution
when(translator.translate("two")).thenReturn("dwa"); // <- stubbing never realized --> UnnecessaryStubbingException thrown

4.2 The Silent Runner

Keeps the Mockito 1 behavior. So no UnnecessaryStubbingException is thrown in the example above.

Annotation - Silent Mockito Runner
// don't detect, old behaviour
@RunWith(MockitoJUnitRunner.Silent.class)

4.3 Practical Hints for the Mockito Runner

When migrating to Mockito 2 the strict runner may help you to detect a lot of unnecessary code in your tests - depending on the current test code quality. The strict runner checks all stubs if they are necessary for the test, if not an UnnecessaryStubbingException is thrown. It is recommend to use the strict runner and remove all the unused stubs in test, since it helps to minimize the amount of code and improves the readability. In huge projects with a lot of tests this might be bigger effort, especially when using abstract test classes. There it might be useful to use the silent runner. But keep in mind the strict runner showed you code smells and the migration effort for a Mockito 3 becomes much bigger.

5 Different Behavior of any Matchers

Mockito matchers anyX() and any(SomeType.class) now reject nulls and check type.

Strict runner example
//code under test:
 ...
 String result = executor.execute(null);
 ...

 //test:
 ...
 when(executor.execute(anyString())).thenReturn("SUCCESS"); // <- no argument of type string used, therefore 'execute' doesn't return "SUCCESS"

5.1 Practical Hints for the Mockito Runner

When migrating to Mockito 2 many tests may fail (depending on the quality of tests), because of this strict behavior of the any matchers. But this strict behavior shows code smells in your code, since there is a difference between null and a real object (e.g., null checks and therefore different execution path)

Recommendation:

  1. Use real objects instead of Matchers, whenever possible!

6  PowerMock

In order to update Mockito it was necessary to update PowerMock as well. To avoid problems like this:

Strict runner example
java.lang.NoClassDefFoundError: org/mockito/cglib/proxy/MethodInterceptor
at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.<init>(PowerMockMaker.java:43)
...
Caused by: java.lang.ClassNotFoundException: org.mockito.cglib.proxy.MethodInterceptor
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 40 more
  1. Replace the api-mockito with api-mockito2.
    Furthermore the powermock-api-mockito-common library is necessary.

    Strict runner example
    -org.powermock:powermock-api-mockito = 1.7.0
    +org.powermock:powermock-api-mockito2 = 1.7.0
    +org.powermock:powermock-api-mockito-common = 1.7.0 

Disclaimer

The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.

Customer Support
Knowledge Base
Product Resources
Support Tickets