首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mockito ClassCastException

Mockito ClassCastException
EN

Stack Overflow用户
提问于 2012-04-26 05:27:03
回答 2查看 20.2K关注 0票数 12

我要测试的方法有一个for循环,其中包含bList中每个元素的逻辑:

代码语言:javascript
运行
复制
class A {
    void someMethod(){

        for(B b: bList){
            //some logic for b
        }
    }
}

执行以下测试时出现异常:

代码语言:javascript
运行
复制
@RunWith(MockitoJUnitRunner.class)
class ATest {

    @Mock
    private B b;

    @Mock
    private Map<Int, List<B>> bMap;

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private List<B> bList;

    @Spy
    @InjectMocks
    private C c;
    ....

    @Test
    public void test(){

        //this line executes fine
        when(bList.size()).thenReturn(1);

        //strangely this works fine
        when(bMap.get(any())).thenReturn(bList);

        //ClassCastException
        when(bList.get(0)).thenReturn(b); // or when(bList.get(anyInt())).thenReturn(b);

        c.methodIWantToTest();
    }
}

我得到的例外是:

代码语言:javascript
运行
复制
java.lang.ClassCastException:
org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$EnhancerByMockitoWithCGLIB$$ cannot be cast to xyz.B

以前有没有人遇到过这种情况,并想出了一个解决办法?

我一直在寻找解决方案,并发现了一些链接:http://code.google.com/p/mockito/issues/detail?id=251http://code.google.com/p/mockito/issues/detail?id=107

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-26 11:13:57

正如this link you posted指出的那样,您遇到了Answers.RETURNS_DEEP_STUBS的错误。

实际上,我没有看到在示例代码中实际使用RETURNS_DEEP_STUBS的任何理由。您真的应该尝试评估是否需要更深的存根,因为作为Mockito docs say,“每当模拟返回模拟时,仙女就会死”。所以,如果可以的话,只要把它拿出来,你的例子就会起作用。

但是,如果您坚持使用深层存根,则可以通过将方法调用的返回值向上转换为Object来避免此错误。例如,将代码中有问题的行替换为:

代码语言:javascript
运行
复制
when((Object)bList.get(0)).thenReturn(b);

话虽如此,我个人还是同意@jhericks的。最好的解决方案可能是使用包含模拟的实际ArrayList,而不是模拟List。唯一的问题是注入你的列表,所以你必须使用@Spy。例如:

代码语言:javascript
运行
复制
@RunWith(MockitoJUnitRunner.class)
class ATest{
  private B b = mock(B.class);
  @Spy
  private List<B> bList = new ArrayList<B>() {{ add(b); }};

  @InjectMocks
  private C c = new C();

  @Test
  public void test(){
    c.methodIWantToTest();
    // verify results
  }
}
票数 20
EN

Stack Overflow用户

发布于 2016-09-14 18:31:31

不幸的是,这是不可能的

案例:API测试:

代码语言:javascript
运行
复制
interface ConfigurationBuilder {...}
configurationBuilder.newServerAction("s1").withName("111")....create();

这种用法的主要原因是编译时的兼容性维护。但是由于java中的类型擦除,mockito不支持带有RETURNS_MOCKS和RETURNS_DEEP_STUBS选项的链中的泛型:

代码语言:javascript
运行
复制
Builder/*<ServerActionBuilder>-erasured generic*/ b = configurationBuilder.newServerAction("s1");
b.withName("111")...create();

上面例子中的结果应该是ServerAction,但在mockito中它是生成的类的对象。

请参阅Issue: Can not Return deep stubs from generic method that returns generic type #484

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10324063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档