You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:20:28