-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
The following repro test fails in an Eclipse OSGi environment when Mockito is applied as a -javaagent
.
package repro;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
class MockitoTest {
@Test
void test() {
var mock = Mockito.mock(org.slf4j.Logger.class);
mock.debug("test");
Mockito.verify(mock).debug("test");
Mockito.verifyNoMoreInteractions(mock);
}
}
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-> at repro.MockitoTest.test(MockitoTest.java:13)
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
at repro.MockitoTest.test(MockitoTest.java:14)
check that
- The mockito message in the stacktrace have useful information, but it didn't help
- The problematic code (if that's possible) is copied here;
Note that some configuration are impossible to mock via Mockito - Provide versions (mockito / jdk / os / any other relevant information)
- mockito:5.14.1
- Java 21.0.4+7-LTS
- Eclipse 2024-09
- Provide a Short, Self Contained, Correct (Compilable), Example of the issue
(same as any question on stackoverflow.com) - Read the contributing guide
Since I cannot provide a full self contained repro, here's what I could debug:
The created mocks do not have a mockInterceptor
set because of a classloader conflict:
The classloader used to load the mock in org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator#mockClass
contains the following classloaders:
- the bundle of the mocked class ("X")
- mockito itself
- context classloader
When MockAccess
is then loaded via that classloader, the EquinoxClassLoader
for "X" is then queried first. That classloader will try to load the class from its parent (i.e. the app classloader) as a last resort.
When the agent is applied, it will find the class there and will not load it from Mockito's classloader.
--> instanceof MockAccess
in org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker#doCreateMock
is then always false:
A fix might be to reorder the classloaders of mockClass()
so that Mockito is always queried first.