独立的饺子 · 使用HtmlUnit库的Java下载器:下载 ...· 2 周前 · |
大方的烤地瓜 · c# 顶级语句 - 不使用 Main ...· 1 周前 · |
彷徨的机器人 · stringvar转变成str ...· 1 周前 · |
留胡子的汤圆 · SharePoint 搜索 REST ...· 5 天前 · |
没有腹肌的开水瓶 · Exception in thread ...· 5 天前 · |
愉快的单车 · ReactiveAuthentication ...· 2 月前 · |
光明磊落的蚂蚁 · 在js中修改html、body的样式_js给 ...· 7 月前 · |
失眠的荒野 · Python下安装OpenGL出现No ...· 11 月前 · |
激动的手套 · 2020-10-06 GIT ...· 1 年前 · |
从容的排球 · redis | 八、redis之Zset ...· 1 年前 · |
我不明白为什么在这里抛出类强制转换异常:
我有一个以字符串的变量作为参数的方法。
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);
}
我已经模拟了方法的实现。
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)
任何加注:
<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 readthe documentation of getArgument(int, Class) for an overview of situations whenthat method is preferred over this one.
我也尝试使用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);
}
这个问题似乎与一个值的varargs有关.如果我为varargs参数传递两个值
@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);
}
这个会很好的。
发布于 2022-10-12 10:46:25
方法在运行时将varargs表示为以数组为其最后一个参数的方法。在源代码中可以将参数作为单独的值传递这一事实是语法上的一种选择。
代码的问题是
i.getArgument(index)
返回每个单独的值-它不会将varargs分组到数组中。
这与不正确的类型推断结合在一起--如果使用i.getArgument(5)调用i.getArgument(5),编译器不正确地假设它需要转换为String[],因此您的代码相当于:
when(myRealService.getSomething(
anyString(),
anyString(),
any(Date.class),
anyString(),
anyString(),
any())
).thenAnswer(i -> {
String[] varargs = i.getArgument(5); // incorrect, Note that code works fine if you use String -> the compiler knows that you are using varargs syntax
return myMockedService.getSomething(
i.getArgument(0),
i.getArgument(1),
i.getArgument(2),
i.getArgument(3),
i.getArgument(4),
varargs
});
例如,您称之为:
myRealService.getSomething("0", "1", new Date(), "3", "4", "5", "6", "7");
的新数组中。
when(myRealService.getSomething(
anyString(),
anyString(),
any(Date.class),
anyString(),
anyString(),
any())
).thenAnswer(i -> {
String[] varargFromInvocation = Arrays.copyOfRange(i.getArguments(), 5, i.getArguments().length, String[].class);
return myMockedService.getSomething(
i.getArgument(0),
i.getArgument(1),
i.getArgument(2),
i.getArgument(3),
i.getArgument(4),
varargFromInvocation);
没有腹肌的开水瓶 · Exception in thread “main“ org.apache.spark.sql.AnalysisException: Cannot write incompatible data to 5 天前 |
从容的排球 · redis | 八、redis之Zset - 墨天轮 1 年前 |