我试图用Mockito 1.9.5模拟一个类,但我有很多麻烦让它工作。
public class Property<T> {
private T value;
public T get() { return this.value; }
public void set(T value) { this.value = value; }
}
public class Model {
private final Property<Integer> count = new Property<Integer>();
public Property<Integer> count() { return this.count; }
}
public class View {
public View(Model model) {
Integer count = model.count().get();
}
}
我写了我的测试样板:
Model model = mock(Model.class, Mockito.RETURNS_MOCKS);
View view = new View(model);
…并得到了一个很长的ClassCastException
:
线程"main"异常java.lang.ClassCastException: org.mockito.internal. create .jmock. classimposterizer $ classwithsuperclassstoworkaroundcglibbug $$Enhancer
ByMockitoWithCGLIB$$cb6ca60b不能强制转换为java.lang.Integer
我知道Mockito不能模拟final
类或原语,但我不知道我需要做什么才能使其工作
类Property<Integer>
的泛型类型在编译期间被擦除。Mockito只能拾取擦除方法的运行时类型。对于Mockito,您的类看起来像这样:
public class Property {
private Object value;
public Object get() { return this.value; }
public void set(Object value) { this.value = value; }
}
模拟该类时,对model.count().get()
的调用隐式地强制转换为Integer
,其中该指令由javac根据您的泛型信息添加。但是,Mockito只在观察到上述类型之后返回Object
类型的mock,因此会出现异常。而不是
mock(Model.class, Mockito.RETURNS_MOCKS);
显式定义返回值
mock(Model.class, Mockito.RETURNS_DEEP_STUBS); // intermediate mocks
when(model.count().get()).thenReturn(0);
Integer
类型是最终的,不能被模拟,这就是为什么你需要返回一个虚拟值。