Document Tree
Document Properties
Kbid
2M8334
Last Modified
04-Feb-2020
Added to KB
30-Jun-2017
Public Access
Everyone
Status
Online
Doc Type
Guidelines
Product
ICM 7.10
Guide - 7.10 Migration Mockito 1 to Mockito 2

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.

References

Major Incompatible Changes

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);

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;

Deprecation

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;

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.*;

Mockito Runner

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

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)

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.

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"

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!

 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.
Home
Knowledge Base
Product Releases
Log on to continue
This Knowledge Base document is reserved for registered customers.
Log on with your Intershop Entra ID to continue.
Write an email to supportadmin@intershop.de if you experience login issues,
or if you want to register as customer.