java - 使用构造函数参数模拟类

标签 java mocking mockito

我需要上一个类进行测试。问题是我正在使用第三方库,其中 class(UpdateManager) 构造函数采用 5 个参数,即一个 java.sql.Connection,其他是字符串。在该构造函数内部,它通过将构造函数参数作为连接传递来创建一个类实例(DataSource)。在该数据源实例中,它调用其调用存储过程的方法之一。我的问题是我通过使用模拟连接传递这 5 个参数来创建 UpdateManager 的部分模拟,但是在构造函数内部调用 DataSource 上的方法时它抛出空指针异常。在我通过下面给出的数据源 stub 之前

Mockito.doNothing().when(dataSource).update(
Mockito.any(DataSource.class),  Mockito.any(ArrayList.class), Mockito.anyInt());

每次构造函数创建 DataSource 的新实例时,仍然会抛出 NullPointException。我如何在没有数据库连接的情况下模拟它,只抛出我的 stub 异常或 doNothing。我使用了 MOCKITO。是否有更好的解决方案使用代理模式。

我们将不胜感激您的建议。

最佳答案

是的,代理类是解决第三方类此类问题的一种方法。然后,您可以简单地模拟您的代理类而不是 3rd 方类,而不会产生任何影响。这种方法的缺点是您最终会使用这些额外的包装器类来支持您的测试。

在这种特定情况下,如果您对创建这些 UpdateManager 对象感兴趣,那么添加一个 Factory 类作为代理可能会有所帮助

public class UpdateManagerFactory {

    public UpdateManager createInstance(... args...) {
        return new UpdateManager(... args...);
    }
}

如果您使用 Spring 或类似工具进行依赖注入(inject),您可以在应用程序上下文中将此工厂作为单例 bean,因此需要使其成为 static。如果你确实想让这个工厂静态,你可以使用 powermockito来 mock 它。

提示:不要害怕添加代码以使您的应用程序更易于测试


编辑您的评论

不要为您的工厂类使用 spy(),而是模拟它

public void myTest() {

    Foo classUnderTest = new Foo();

    UpdateManagerFactory umf = mock(UpdateManagerFactory.class);

    UpdateManager um = mock(UpdateManager.class);

    when(umf.createInstance()).thenReturn(um);

    // perform test that will call umf.createInstance() at some point
    classUnderTest.doSomething();

    // verify + assert on "umf" and "um"

}

关于java - 使用构造函数参数模拟类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14751321/

相关文章:

java - 为 JUnit 类别创建注解

java - 当 similarly if-else 增长时应该使用什么设计模式?

python - 测试类中所有测试用例的模拟导入方法

java - 如何摆脱 Mockito mock Uninitialized read findbugs 警告

java - 如何在 mockito 中模拟日期?

java - 如何验证没有调用模拟对象的方法?莫基托

java - 无法从内部类访问包含类方法

java - spring-data-mongodb:如何通过传递随机属性及其值来查找文档

java - 如何使用 Mockito 为不同的参数设置不同的返回类型?

android - 如何在android单元测试中模拟Resources类以获得scaledDensity?