After so many years of hopeless waiting, Mockito 2.x has been released to solve many problems that developers have had with their tests.

There are great features of Mockito 2.x, such as:

Finally mocking final classes and methods.

Support for Java 8.

Migration from CGLIB to ByteBuddy.

But if you are having large tests written in Mockito 1.x, will it be an easy task to migrate?

Unfortunately, the migration most probably will be a painful task because Mockito 2.x does not respect the old behavior of Mockito 1.x. Adding to this complexity, If you use PowerMock in your old tests, then you will have to face another dimension of complexity, as most of PowerMock’s versions have integration issues with Mockito 2.x.

Regarding PowerMock’s early issues with Mockito 2.x, the PowerMock team announced that PowerMock 1.6.5 has experimental support for Mockito 2.x but unfortunately, it was not that great.

In the beginning, when changing the Mockito version to 2.x in your build.gradle file, you may find that more than 50% of your tests were failing: Null pointer exceptions, compilation errors, No class definition found, unexpected thrown exception, …etc, and this is how you might look in the beginning of the migration.

Do not panic and do not be sad, this artivle mentions some of the important challenges that you may face during the migration and tips to overcome these challenges to save your time.

1. Use the Proper PowerMock’s Mockito API Extension

Using the powermock-api-mockito extension does not work with Mockito 2.x. You will have the following exception when running your unit tests if you stick to the old extension:

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

In order to fix this issue, you should use the correct Mockito API extension, which is:powermock-api-mockito2.

2. Avoid Using Incompatible Versions of Mockito and PowerMock

Always make sure to use compatible versions of Mockito and PowerMock. For example, the following two versions are compatible:

PowerMock version 1.7.0 RC2.

Mockito version 2.1.0.

3. Say Goodbye to Mockito’s Whitebox

Mockito 2.x does not have Whitebox anymore.

So what is the solution then?

Initially, you can use PowerMock’s Whitebox instead of the removed Mockito 2.x Whitebox. However, you need to know that this does not come without problems, such as this one that I reported to PowerMock:

org.powermock.reflect.exceptions.FieldNotFoundException: No instance field named XXX could be found in the class hierarchy

So if the initial solution does not work for you, consider writing your own. It's really not that hard.

4. Using the Right Matchers

Never forget to always use org.mockito.ArgumentMatchers instead of the old org.mockito.Matchers.

So in summary, if you use Mockito 2.7.1, do not forget to use PowerMock 1.7.0RC4.

8. Original Test Exceptions Are Wrapped as RuntimeExceptionProxy in Mockito 2.x With PowerMock

Unfortunately, as a workaround, you have to modify all the broken @Test(expected=SomeException.class) to @Test(expected=Exception.class) since the original exceptions are wrapped as Mockito RuntimeExceptionProxy in Mockito 2.x with PowerMock.

This issue really requires further investigation to know why Mockito 2.x does this wrapping with PowerMock. If you have a better solution for this, feel free to comment.

9. Move Away from PowerMock and Depend on Mockito 2.x Only

Try to create a plan to remove PowerMock by refactoring your app classes to be testable. Mockito 2.x is really enough now.

10. Review Old Tests

Take this migration as a chance to review the old tests and to improve them in order to have more maintainable tests. This can help you strengthen your product code and allow easier refactoring for the current code base without surprises.