java – Mockito ClassCastException
The method I want to test has a for loop and the logic of each element in blist:
class A { void someMethod(){ for(B b: bList){ //some logic for b } } }
I get an exception when I perform the following tests:
@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(); } }
The exceptions I get are:
java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundcglibBug$$EnhancerByMockitoWithcglib$$cannot be cast to xyz.B
Has anyone encountered it before and proposed a solution?
I have searched for a solution and encountered some links: http://code.google.com/p/mockito/issues/detail?id=251 And http://code.google.com/p/mockito/issues/detail?id=107
Solution
As shown in this link you posted, you have encountered answers RETURNS_ DEEP_ Stubs error
In fact, I don't see any reason to actually use returns in your sample code_ DEEP_ STUBS. You really should try to assess whether you need deep stubs, because, as mockito docs say, "imitate one fairy tale death at a time" So if you can, just take it out and your example will do
However, if you insist on using deep stubs, you can solve this error by calling the return value to the object conversion method For example, replace the offending line in the code with the following code:
when((Object)bList.get(0)).thenReturn(b);
All this, I personally agree @jhericks The best solution might be to use an actual ArrayList containing your simulation instead of a mockery list The only problem is to get your list injected, so you must use @ spy For example:
@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 } }