-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
All right, we have been talking about this for a while so let's consolidate discussions. TLDR: more and more use cases are broken (by default) with Mockito and JDK 17. That's because the subclass mockmaker runs into fundamental limitations on JDK 17, but the inline mockmaker works as expected.
There are a lot of issues related to this:
- Spying on interfaces with default methods does not work anymore with JDK 17 (Temurin) #2587
- mock(SecureRandom.class) and mock(Random.class) fails #2560
- Spies don't behave properly when running in Java 17 #2573
- Mockito silently produces incorrect mocks of jdk classes with java 17 #2561 (suspected)
- Cannot execute any tests in JDK17 envir. Error: "NoSuchMethodException: sun.misc.Unsafe.defineClass(...) " #2521 (suspected)
- InjectMocks and Spy annotations are no more working in Java 17 #2449 (suspected)
At this point, the rate of issues created is increasing, as more and more of our users are adopting JDK 17+
We have historically talked about this as well: #1728
When chatting with @raphw about this issue, there were a couple of options that we have available:
- Keep on using the subclass mockmaker by default on all JDK's and suggest users to use
mockito-inline
whenever appropriate - Switch the default to the inline mockmaker for all JDK's and put the subclass mockmaker in an artifact such as
mockito-subclass
(legacy) - Detect the current JDK version and make the inline mockmaker the default on JDK 17+, but keep the subclass mockmaker the default for older JDK versions
In my opinion, we should opt for least amount of surprise. E.g. Mockito should "just" work out-of-the-box for the majority of use cases. Therefore, if Mockito (by default) does not work nicely with JDK 17 in more and more cases, I consider that a bug.
That said, I don't think it is a good choice to force all existing users that are on JDK 16 and below to update their codebase wholesale to the new mockmaker. Inheritently, the new mockmaker works slightly different and forcing the update onto users doesn't feel like a nice solution. In the end, it works just fine on JDK 16 on below, so why change it?
Therefore, my proposed way forward is:
- We publish Mockito 5 which switches the default mockmaker to the inline mockmaker on JDK 17+
- We update the JavaDoc of the subclass mockmaker to make users aware it is only intended to be used for specific use cases
In terms of timeline, I think we should collective user feedback from the community first. This issue seems like the best place to do so. Once we are confident that we would be able to switch the default, we could publish Mockito 5. For now, what if we take June 2022 as a temporary date to make such a change, unless we receive strong/valid user feedback that should block such a change?
CC @mockito/developers