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
  }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>