gpt4 book ai didi

java - 使用 Mockito 模拟泛型类型时出现 ClassCastException

转载 作者:行者123 更新时间:2023-12-01 17:09:30 26 4
gpt4 key购买 nike

我有一个带有通用参数的抽象测试类。

public abstract class AbstractCarTest<G> {
...
@Mock
protected G carMock;
...
}

我已经实现了它的具体测试类。

public class TruckTest extends AbstractCarTest<Truck> {
...
when(truckFactory.getTruck(anyString()).return(carMock);
...
}

方法签名如下所示

public Truck getTruck(String name);

运行TruckTest时,我收到一个ClassCastException

java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$EnhancerByMockitoWithCGLIB$$... cannot be cast to com.example.Truck

这是为什么呢?有什么办法可以解决这个问题吗?

最佳答案

Mockito 正在运行时生成您的模拟类。模拟是通过子类化给定类并覆盖其所有方法来创建的。 (因此限制了不模拟 final 类或方法。)在运行时,所有 generic types are erased并替换为其类型上限,在您的 AbstractCarTest 中,这是 Object,因为您没有指定显式上限。因此,Mockito 将您的原始类视为:

public abstract class AbstractCarTest {

@Mock
protected Object carMock;
}

在运行时,将创建一个扩展Object而不是您所需的Truck类的模拟。 (您看不到这一点,因为 cglib 有一个错误,它无法直接扩展 Object。相反,Mockito 正在扩展一个名为 ClassWithSuperclassToWorkAroundCglibBug 的内部类。)通常,编译器会发出编译时出现类型错误,泛型类型仍然可用,但在运行时,您会遇到 heap pollution相反。

解决方法如下:

public abstract class AbstractCarTest<T> {

protected abstract T getCarMock();

// define some base test cases here that use the generic type.
}

public class TruckTest extends AbstractCarTest<Truck> {

@Mock
private Truck carMock;

@Override
protected Truck getCarMock() { return carMock; }

// ...
when(truckFactory.getTruck(anyString()).return(getCarMock());
}

通过在不使用泛型的情况下定义模拟类型,您可以通过 getter 从抽象基类访问模拟,其中模拟类型被正确定义为 Truck

关于java - 使用 Mockito 模拟泛型类型时出现 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24302535/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com