Mockito中Varargs参数when-thenAnswer抛出类型转换异常问题
可变参数Mockito单元测试中的类型转换异常问题
我无法理解为何以下代码会抛出类型转换异常,具体情况如下:
我有一个接收String类型可变参数的方法:
public List<A> getSomething(final String a, final String b, final Date c, final String d, final String e, final String... f) throws MyException { return valuesFromDB(a, b, c, d, e, f); }
我为该方法编写了Mock实现:
public List<A> getSomethingUnitTest(final String a, final String b, final Date c, final String d, final String e, final String... f) throws MyException { return valuesFromCSV(a, b, c, d, e, f); }
在使用Mockito的单元测试中,我编写了如下代码:
@ExtendWith(MockitoExtension.class) class AlgoTest { @Test void testExecute() throws MyException { when(myRealService.getSomething(anyString(), anyString(), any(Date.class), anyString(), anyString(), any())) .thenAnswer(i -> myMockedService.getSomethingUnitTest(i.getArgument(0), i.getArgument(1), i.getArgument(2), i.getArgument(3), i.getArgument(4), i.getArgument(5))); Output output = algo.execute(); assertNotNull(output); } }
运行测试时抛出类型转换异常:
java.lang.ClassCastException: class java.lang.String cannot be cast to class [Ljava.lang.String; (java.lang.String and [Ljava.lang.String; are in module java.base of loader 'bootstrap') at com.cmystuff.alghorithm.AlgoTest.lambda$2(AlgoTest.java:82) at org.mockito.internal.stubbing.StubbedInvocationMatcher.answer(StubbedInvocationMatcher.java:40) at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:99) at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29) at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:33) 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.interceptSuperCallable(MockMethodInterceptor.java:141)
查看相关方法文档:
any()方法文档:
<String[]> String[] org.mockito.ArgumentMatchers.any() Matches anything, including nulls and varargs.
getArgument()方法文档:
<String[]> String[] org.mockito.invocation.InvocationOnMock.getArgument(int index) Returns casted argument at the given index. Can lookup in expanded arguments form getArguments(). This method is preferred over getArgument(int, Class) for readability. Please read the documentation of getArgument(int, Class) for an overview of situations when that method is preferred over this one.
我尝试将any()替换为anyString(),依然抛出相同的类型转换异常:
@ExtendWith(MockitoExtension.class) class AlgoTest { @Test void testExecute() throws MyException { when(myRealService.getSomething(anyString(), anyString(), any(Date.class), anyString(), anyString(), anyString())) .thenAnswer(i -> myMockedService.getSomethingUnitTest(i.getArgument(0), i.getArgument(1), i.getArgument(2), i.getArgument(3), i.getArgument(4), i.getArgument(5))); Output output = algo.execute(); assertNotNull(output); } }
我发现问题似乎和可变参数仅传递一个值有关:如果我为可变参数传递两个值,测试就能正常运行:
@ExtendWith(MockitoExtension.class) class AlgoTest { @Test void testExecute() throws MyException { when(myRealService.getSomething(anyString(), anyString(), any(Date.class), anyString(), anyString(), anyString(), anyString())) .thenAnswer(i -> myMockedService.getSomethingUnitTest(i.getArgument(0), i.getArgument(1), i.getArgument(2), i.getArgument(3), i.getArgument(4), i.getArgument(5), i.getArgument(6))); Output output = algo.execute(); assertNotNull(output); } }
内容的提问来源于stack exchange,提问作者Paul Marcelin Bejan
相关产品推荐
相关产品推荐

