-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Closed
Labels
Description
Consider the following code:
@ExtendWith(MockitoExtension.class)
public class MockitoTest {
@Mock MyService myService;
@Test
public void test() {
Mockito.when(
myService.doSomething(
and(any(MyPojo.class),
argThat(p -> p.id == 1))))
.thenReturn(1);
myService.doSomething("hello");
}
interface MyService {
int doSomething(Object pojo);
}
static class MyPojo {
int id = 1;
}
}
This test throws the following exception:
java.lang.ClassCastException: class java.lang.String cannot be cast to class MockitoTest$MyPojo (java.lang.String is in module java.base of loader 'bootstrap'; MockitoTest$MyPojo is in unnamed module of loader 'app')
at org.mockito.internal.matchers.And.matches(And.java:23)
at org.mockito.internal.invocation.TypeSafeMatching.apply(TypeSafeMatching.java:35)
at org.mockito.internal.invocation.MatcherApplicationStrategy.argsMatch(MatcherApplicationStrategy.java:85)
at org.mockito.internal.invocation.MatcherApplicationStrategy.forEachMatcherAndArgument(MatcherApplicationStrategy.java:71)
at org.mockito.internal.invocation.InvocationMatcher.argumentsMatch(InvocationMatcher.java:156)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:82)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:92)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:91)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:34)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:82)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:56)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptAbstract(MockMethodInterceptor.java:161)
at MockitoTest$MyService$MockitoMock$v3DeXXsQ.doSomething(Unknown Source)
at MockitoTest.test(MockitoTest.java:23)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
Debugger inspection of And.matches()
shows that m1
is the lambda and m2
is the InstanceOf
, as opposed to what was passed to and()
. I guess this comes from ArgumentMatcherStorageImpl#reportAnd()
and reportOr()
which pop m1
before m2
, swapping the order.
This is with Mockito 5.11.0, Junit 5.10.2 and Java 11.
check that
- The mockito message in the stacktrace have useful information, but it didn't help
No, it does not provide useful information (here the exception is similar to the one in argThat throws ClassCastException upon different subclass instance than for the ArgumentMatcher generic type #2268 but it could be something else like an NPE, depending on the use case) - 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)
- Provide a Short, Self Contained, Correct (Compilable), Example of the issue
(same as any question on stackoverflow.com) - Read the contributing guide