简体   繁体   English

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

[英]Mocking methods that return generics and primitives with Mockito

I'm trying to mock a class using Mockito 1.9.5 but I'm having a lot of trouble getting it to work. 我正在尝试使用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();
    }
}

I wrote my test boilerplate: 我写了我的测试样板:

Model model = mock(Model.class, Mockito.RETURNS_MOCKS);
View view = new View(model);

... and got a long ClassCastException : ...并且有一个很长的ClassCastException

Exception in thread "main" java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$Enhancer 线程“主”中的异常java.lang.ClassCastException:org.mockito.internal.creation.jmock.ClassImposterizer $ ClassWithSuperclassToWorkAroundCglibBug $$ Enhancer

ByMockitoWithCGLIB$$cb6ca60b cannot be cast to java.lang.Integer ByMockitoWithCGLIB $$ cb6ca60b无法强制转换为java.lang.Integer

I know that Mockito can't mock final classes or primitives, but I'm at a loss for what I need to do to make this work. 我知道Mockito不能模拟final类或基元,但是我不知所措,无法完成这项工作。

The generic type of your class Property<Integer> is erased during compilation. Property<Integer>的泛型类型在编译期间被擦除。 Mockito can only pick up the runtime type of your erased method. Mockito只能选择已擦除方法的运行时类型。 To Mockito, your class looks something like this: 对于Mockito,您的课程看起来像这样:

public class Property {
  private Object value;
  public Object get() { return this.value; }
  public void set(Object value) { this.value = value; }
}

When you mock this class, your call to model.count().get() is implicitly cast to Integer where this instruction is added by javac due to your generic information. 模拟该类时,对model.count().get()调用将隐式转换为Integer ,由于您的通用信息, javac会在此添加此指令。 However, Mockito only returns a mock of an Object type after it observed the types above, thus the exception. 但是,Mockito在观察到上述类型之后才返回Object类型的模拟,因此是异常。 Instead of 代替

mock(Model.class, Mockito.RETURNS_MOCKS);

define the return value explicitly 明确定义返回值

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

The Integer type is final and cannot be mocked which is why you need to return a dummy value. Integer类型是最终类型,不能被模拟,这就是为什么您需要返回一个虚拟值的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM