【问题标题】:How does mockito create an instance of the mock objectmockito如何创建mock对象的实例
【发布时间】:2010-06-29 05:47:57
【问题描述】:

当我创建一个说类 Employee 的模拟对象时。它不调用 Employee 对象的构造函数。我知道内部 Mockito 使用 CGLIb 和反射,创建一个代理类,将类扩展为模拟。如果不调用employee的构造函数,怎么创建employee类的mock实例?

【问题讨论】:

标签: java testing constructor mockito


【解决方案1】:

Mockito 使用 CGLib 生成类对象。但是要实例化这个类对象,它使用 Objenesis http://objenesis.org/tutorial.html

Objenesis 能够使用各种技术(即调用 ObjectStream.readObject 和类似方法)在没有构造函数的情况下实例化对象。

【讨论】:

  • Objenesis 的链接断开
  • 显然他们搬到了新的领域,项目现在在 github 上。我修复了链接
【解决方案2】:

Mockito 使用反射和 CGLib 以动态创建的超类来扩展 Employee 类。作为其中的一部分,它首先将 Employee 的所有构造函数公开 - 包括默认构造函数,如果你声明了一个带参数的构造函数,它仍然存在但私有。

public <T> T imposterise(final MethodInterceptor interceptor, Class<T> mockedType, Class<?>... ancillaryTypes) {
    try {
        setConstructorsAccessible(mockedType, true);
        Class<?> proxyClass = createProxyClass(mockedType, ancillaryTypes);
        return mockedType.cast(createProxy(proxyClass, interceptor));
    } finally {
        setConstructorsAccessible(mockedType, false);
    }
}

private void setConstructorsAccessible(Class<?> mockedType, boolean accessible) {
    for (Constructor<?> constructor : mockedType.getDeclaredConstructors()) {
        constructor.setAccessible(accessible);
    }
}

我假设它在创建超类时调用了默认构造函数,尽管我还没有测试过。您可以通过声明私有默认构造函数 Employee() 并在其中添加一些日志来自己测试它。

【讨论】:

  • 它在任何时候都不会调用默认构造函数。
  • 谢谢,我很好奇。
  • Mockito调用生成类的构造函数(大概是为了避免调用目标类型的构造函数的副作用)
猜你喜欢
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多