【问题标题】:Mocking methods that return generics and primitives with Mockito使用 Mockito 返回泛型和原语的模拟方法
【发布时间】:2014-08-13 02:57:12
【问题描述】:

我正在尝试使用 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.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$Enhancer

ByMockitoWithCGLIB$$cb6ca60b 不能转换为 java.lang.Integer

我知道 Mockito 不能模拟 final 类或原语,但我不知道我需要做些什么才能完成这项工作。

【问题讨论】:

  • 我猜它不起作用,因为model.count().get() 返回Object,而不是Integer。您可能需要模拟count 并将其注入Model
  • @AndrewLogvinov 问题是我的Model 类中有很多属性,为所有这些类编写模拟非常耗时。我认为模拟框架的目的是让我免于手动编写大量样板......

标签: java unit-testing generics mockito


【解决方案1】:

您的类Property&lt;Integer&gt; 的泛型类型在编译期间被删除。 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 类型是最终的,不能被模拟,这就是你需要返回一个虚拟值的原因。

【讨论】:

  • 我在when(model.count().get()).thenReturn(0); 上收到了NullPointerException。如果我切换到Model model = mock(Model.class, Mockito.RETURNS_DEEP_STUBS);,那么它会毫无例外地运行。不过,必须手动指定虚拟属性仍然非常繁琐。
  • 您需要模拟中间类,请参阅我更新的答案。当类型被擦除时,Mockito 无法知道此类应该是整数。这是 Java 类型系统的一个简单限制,与此无关。即使它知道这一点,Mockito 也无法模拟 Integer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2020-01-21
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
  • 2014-11-27
  • 1970-01-01
相关资源
最近更新 更多