Mockito ClassCastException -无法转换模拟

vsaztqbk  于 2022-11-23  发布在  其他
关注(0)|答案(5)|浏览(323)

我想测试类AppleProcessor中的一个方法:

public void process(Fruit fruit) {
    if(fruit.getType() == Fruit.APPLE) {
        fruitBasket.add(((AppleFruit) fruit).getApple());
    }
    else {
        // do something else
    }
}

请注意,Fruit是一个带有getType()方法的接口,该方法由AppleFruit实现,并且还有一个getApple()方法。
我的测试如下所示:

@Mock
FruitBasket fruitBasket;

@Mock
Fruit fruit;

@Mock
AppleFruit apple;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void testAnAppleIsProcessed() {
    AppleProcessor appleProcessor = new AppleProcessoer();
    when(fruit.getType()).thenReturn(Fruit.APPLE);
    when(((AppleFruit) fruit).getApple()).thenReturn(apple);

    appleProcessor.process(fruit);

    verify(fruitBasket).add(isA(Apple.class));
}

但是,我得到以下错误:
java.lang.ClassCastException: package.fruit.Fruit$$EnhancerByMockitoWithCGLIB$$b8254f54 cannot be cast to package.fruit.AppleFruit
它来自测试中的这一行
when(((AppleFruit) fruit).getApple()).thenReturn(apple);
有人知道如何解决这个问题,以便我可以测试我的代码吗?

66bbxpm5

66bbxpm51#

当你说

@Mock
Fruit fruit;

你告诉Mockito:变量fruit应该是Fruit的一个示例。Mockito将动态创建一个实现Fruit的类(该类是Fruit$$EnhancerByMockitoWithCGLIB$$b8254f54),并创建该类的一个示例。该类没有理由是AppleFruit的一个示例,因为您没有告诉Mockito该对象必须是AppleFruit类型。
将它声明为AppleFruit,它的类型将为AppleFruit

0lvr5msh

0lvr5msh2#

任何人搜索这只是包括:

@Mock(extraInterfaces = {AppleFruit.class})
Fruit fruit;

这将向mock添加一个额外的接口,并且转换不会引发任何异常。

lymnna71

lymnna713#

Mockito可以处理在模拟时间(赋值)已经被强制转换的模拟对象。但是,它不会在代码执行期间自己强制转换一个模拟对象。
换句话说(或者更好的是代码):

Fruit fruit = Mockito.mock(Applefruit.class);

只要按照JB Nizet说的去做,你就会没事的。我也遇到过类似的问题,他的解决方案奏效了。
对于这个问题,它将是:

@Mock
FruitBasket fruitBasket;

@Mock
AppleFruit fruit; // changed here

@Mock
AppleFruit apple;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void testAnAppleIsProcessed() {
    AppleProcessor appleProcessor = new AppleProcessoer();
    when(fruit.getType()).thenReturn(Fruit.APPLE);
    when(((AppleFruit) fruit).getApple()).thenReturn(apple);

    appleProcessor.process(fruit);

    verify(fruitBasket).add(isA(Apple.class));
}

这就是所需要的一切。

t8e9dugd

t8e9dugd4#

对于返回超类对象的方法,你可以让mockito返回子类类型的对象,这样就不需要让mockito强制转换对象了。

qzlgjiam

qzlgjiam5#

您的mock对象是由Mockito增强的,它与您的类不同,因此您不能进行类型转换。

相关问题