使用Mockito返回返回泛型和基元的方法

时间:2014-08-12 18:13:04

标签: java unit-testing generics mockito

我试图使用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

  

线程中的异常&#34; main&#34; java.lang.ClassCastException:org.mockito.internal.creation.jmock.ClassImposterizer $ ClassWithSuperclassToWorkAroundCglibBug $$ Enhancer

     

ByMockitoWithCGLIB $$ cb6ca60b无法强制转换为java.lang.Integer

我知道Mockito不能模仿final课程或原语,但我为实现这项工作需要做的事情而感到茫然。

1 个答案:

答案 0 :(得分:2)

编译期间将删除类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(Model.class, Mockito.RETURNS_MOCKS);

明确定义返回值

mock(Model.class, Mockito.RETURNS_DEEP_STUBS); // intermediate mocks
when(model.count().get()).thenReturn(0);

Integer类型是final,无法模拟,这就是您需要返回虚拟值的原因。