【问题标题】:Mocking static method in Java在Java中模拟静态方法
【发布时间】:2020-03-08 15:59:39
【问题描述】:

有没有办法在不执行方法实际实现的情况下模拟 Java 中的单元测试静态方法?实际实现会启动在单元测试上下文中无法完成的过程。


public class MyExecutor {

    public static int execute(...) {
        Process pr = Runtime.getRuntime().exec(...)
        int status = pr.waitFor();
        return status;
    }


public MyClass {

    public void methodToUnitTest(...){

        MyExecutor.execute(...)

    }

我想模拟 MyExecutor.execute 并在单元测试 MyClass.methodToUnitTest 但没有实际执行此方法时验证它的调用及其参数。

我读到 PowerMockito 可以模拟静态方法,但它不会阻止执行实际实现。

【问题讨论】:

标签: java unit-testing


【解决方案1】:

将静态类MyExecutor 包装在一个非静态类中。将新的非静态类的方法提取到接口中。用接口替换静态类的依赖——使用依赖注入将MyExecutor实例提供给MyClass

public MyExecutorAdapter implements Executor{

  public void execute() {
     MyExecutor.execute()    //call to static code
  }

}

public MyClass {
  private Executor myExecutor;

  public MyClass(Executor myExecutor){   //MyExecutorAdapter instance can be injected here
    this.myExecutor = myExecutor;
  }  

  public void methodToUnitTest(...){
    myExecutor.execute(...)
  }
}

现在,使用该接口,您可以轻松地模拟或提供假实现以进行测试。在您的情况下,您可能需要一个模拟来检查是否调用了 execute 方法。

这基本上被称为Adapter pattern

【讨论】:

  • 我想过注入 MyExecutor 类。但这意味着本质上是静态的类变成了非静态的。
  • 您正在注入执行静态类代码的包装类的实例。 MyExecutor 类保持静态,没有任何变化。
  • 没关系。您注入的类是非静态的。实际上,这个解决方案比将静态方法类设为非静态并注入它更复杂。我想知道是否有任何测试框架可以在不进行任何重构的情况下模拟静态类。
  • 从设计的角度来看,这是一个更好的解决方案。你有更多的灵活性,可以使用依赖注入。其他建议是使用 PowerMock:github.com/powermock/powermock 虽然在决定使用它之前阅读了他们自述文件的第一段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多