使用构造函数参数模拟类

Ani*_*nil 5 java mocking mockito

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

Mockito.doNothing().when(dataSource).update(
Mockito.any(DataSource.class),  Mockito.any(ArrayList.class), Mockito.anyInt());
Run Code Online (Sandbox Code Playgroud)

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

您的建议将不胜感激。

Bra*_*rad 2

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

在这种特定情况下,添加一个工厂类来充当代理可能会对您有利,因为您对创建这些UpdateManager对象感兴趣

public class UpdateManagerFactory {

    public UpdateManager createInstance(... args...) {
        return new UpdateManager(... args...);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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


根据您的评论进行编辑

不要在 Factory 类中使​​用间谍(),而是模拟它

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"

}
Run Code Online (Sandbox Code Playgroud)