Mockito error in Spring Boot tests after migrating to JDK 11
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Moving a Spring Boot project from Java 8 to JDK 11 often breaks tests before it breaks production code. Mockito-based tests are a common pain point because the upgrade exposes older dependencies, reflective-access assumptions, and outdated JUnit integration patterns that were tolerated on older JDKs.
The fix is usually not one JVM flag or one annotation change. You need to check dependency versions, modernize how mocks are initialized, and separate plain Mockito tests from Spring context tests.
Why JDK 11 Exposes Mockito Problems
Mockito creates mocks through bytecode generation and reflective access. JDK 11 did not make Mockito unusable, but it did make old testing stacks much less forgiving. Teams commonly see:
- '
InaccessibleObjectException' - illegal reflective access warnings
- failures when mocking final classes or JDK types
- tests that work in one module but fail in another because the dependency graph differs
In practice, the root cause is often one of these:
- '
mockito-coreis too old' - '
byte-buddyis too old' - JUnit 4 and JUnit 5 styles are mixed
- '
MockitoAnnotations.initMocksis still being used from old examples' - PowerMock or another library is doing deeper bytecode tricks than Mockito itself
Align The Test Dependencies First
If Spring Boot manages your dependency versions, let it. Many migration bugs come from overriding Mockito or JUnit versions partially and ending up with a stack that compiles but behaves badly at runtime.
A clean Gradle setup for JUnit 5 looks like this:
That does two important things:
- it keeps Spring Boot's managed test dependencies in place
- it ensures the test task is actually using the JUnit Platform
Without useJUnitPlatform(), developers sometimes think Mockito is failing when the real issue is that the wrong test engine is executing the suite.
Prefer The JUnit 5 Mockito Extension
For plain unit tests, the most robust setup is to use the Mockito JUnit 5 extension instead of manually opening mocks:
This avoids a lot of fragile setup code and matches the current Mockito style much better than older runner-based examples.
Use openMocks If You Need Manual Lifecycle Control
Sometimes you do not want to use the extension directly. In that case, use MockitoAnnotations.openMocks(this) rather than the older initMocks pattern:
That may look minor, but migration problems often come from copying older snippets that predate current Mockito guidance.
Know When Spring Boot Should Mock For You
A plain Mockito unit test is not the same thing as a Spring Boot test that loads an application context. If the Spring container is involved, you often want @MockBean so that Spring replaces the real bean in the context.
If you use plain @Mock in a Spring context test, the application may still wire the real bean, and the failure can look unrelated to mocking.
When The Real Problem Is Not Mockito
A JDK 11 migration often reveals deeper issues in the test stack. PowerMock is a frequent example because it depends heavily on internals and can fail in situations where modern Mockito works fine. Another case is adding a pile of --add-opens flags to keep old tests limping along. That can be a temporary bridge, but it is usually a sign that the real fix is dependency modernization.
The right debugging order is:
- confirm the exact failing dependency versions
- isolate whether the failure happens in plain Mockito or only in Spring Boot tests
- check whether PowerMock or another older tool is involved
- remove unnecessary custom JVM flags before assuming the JDK itself is broken
Common Pitfalls
- Upgrading the JDK without upgrading the test dependency stack.
- Mixing JUnit 4 runners and JUnit 5 extensions in the same suite.
- Using
initMocksfrom older examples instead of current Mockito initialization patterns. - Using plain Mockito mocks in a Spring context test when
@MockBeanis needed. - Blaming Mockito for failures that actually come from PowerMock, Byte Buddy version drift, or stale build configuration.
Summary
- JDK 11 often exposes old Mockito and test-stack assumptions rather than creating a brand-new Mockito problem.
- Start by aligning Spring Boot, Mockito, Byte Buddy, and JUnit versions.
- Prefer
@ExtendWith(MockitoExtension.class)for plain unit tests. - Use
MockitoAnnotations.openMocksif you need manual initialization. - In Spring Boot context tests, use
@MockBeanwhen the container must replace a real bean.

