我想测试的方法有一个for循环与bList中的每个元素的逻辑:
class A { void someMethod(){ for(B b: bList){ //some logic for b } } }
执行以下测试时我得到一个异常:
@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(); } }
我得到的例外是:
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=251
和
http://code.google.com/p/mockito/issues/detail?id=107
解决方法
如
this link you posted所示,您遇到了Answers.RETURNS_DEEP_STUBS的错误.
实际上我没有看到任何理由在您的示例代码中实际使用RETURNS_DEEP_STUBS.你真的应该尝试评估你是否需要深刻的存根,因为,作为Mockito docs say,“每次模拟一个模仿一个童话死亡”.所以如果可以的话,只需把它拿出来,你的例子就可以了.
但是,如果您坚持使用深层存根,则可以通过向Object转换方法调用返回值来解决此错误.例如,使用以下代码替换代码中的违规行:
when((Object)bList.get(0)).thenReturn(b);
所有这一切,我个人同意@jhericks.最好的解决方案可能是使用一个包含你的模拟的实际的ArrayList,而不是嘲笑List.唯一的问题就是让你的列表被注入,所以你必须使用@Spy.例如:
@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 } }