繁体   English   中英

BDDMockito `given(...).willReturn(...)` 只调用一次模拟,而不是每次调用 `given()` 函数

[英]BDDMockito `given(...).willReturn(...)` calls the mock just once instead of each call to the `given()` function

我在一个实用程序类中定义了一个静态方法,它在 Unix 环境中执行 shell 命令:

public final class Shell {
    
    public static String execute(String[] commands, long timeout) {
        //do stuff
    }

}

此方法用于在环境中执行 Bash 命令,这意味着我们不仅有一个包含特定命令输出的String作为返回值,而且命令本身的一些影响可能会发生。

例如,在特定情况下,该命令会生成一个.out文件并将操作的状态作为String

出于测试目的,我需要模拟此调用。 因此,我需要它来生成.out文件作为模拟并返回一些东西。 为此,我使用了BDDMockitoPowerMockito ,如下所示:

PowerMockito.mockStatic(Shell.class);
BDDMockito.given(Shell.execute(eq(specificArgument), anyLong()).willReturn(mock_out_execution());

...其中mock_out_execution()是一个函数,它在工作目录上创建.out文件,然后返回成功状态 - 模拟在真实 Unix 环境中的执行。

背景信息: .out文件由读取它的进程处理,执行某些操作然后将其删除。 此信息对于了解我的问题很重要。

现在,在我的集成测试执行期间,

  • 第一次调用Shellexecute()方法。 .out文件被创建。
  • .out文件因此被主线程处理和删除
  • Shellexecute()方法被第二次调用。 应该再次创建.out文件。
  • 因此,应再次处理.out文件,并在完成后将其删除。

问题是BDDMockito.given(...).willReturn(...)在模拟初始化时只执行一次。 这意味着第一次execute().out文件就在那里,进程可以处理它。 但是,第二次execute() ,不会再次执行任何操作,因此新的.out文件丢失,代码执行失败。

我该如何解决这个问题? 每次调用我想要模拟的方法时,使用PowerMockito实际调用模拟的正确方法是什么?

当您使用willReturn您将传递一个常量对象,该对象将被立即计算。 如果你想返回一些动态的东西,这是每次调用的调用时刻单独计算的,你必须使用willAnswer()

您传递的答案对象基本上是一个函数,用于将调用(有关调用的所有数据都在此对象中)转换为每次调用的具体结果。


编辑:

试过这个,效果很好。 也许这有助于比较笔记:

// Mocked service
package stuff;

public class StaticService {
   public static String fetchStuff() {
      return "Stuff";
   }
}


// Test class
package stuff;

import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "stuff.StaticService")
public class PowerMockitoTest {
   @Test
   public void testStatic() {
      PowerMockito.mockStatic(StaticService.class);
      AtomicInteger cnt = new AtomicInteger(0);
      BDDMockito.given(StaticService.fetchStuff()).willAnswer(invocation -> Integer.toString(cnt.getAndIncrement()));
      System.out.println(StaticService.fetchStuff());
      System.out.println(StaticService.fetchStuff());
   }
}

结果

0
1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM