如何从应用程序上下文注入 Junit5 Mockito 中的模拟?

How to inject from application context into a mock in Junit5 Mockito?

我必须在我的 Java 应用程序中为 MyUtility.class 实施单元测试。但是,它依赖于 MyConfig.class(它从 application.yml 文件中获取配置属性)。

class MyUtility {

  MyConfig myConfig;

  @Autowired
  public MyUtility(MyConfig myConfig) {
   this.myConfig = myConfig;
  }

  public String methodA() {

    ... // use myConfig.getValue() to perform some operation

    methodB(); // call methodB()

    ...
  }

  public String methodB() { ... }
}
@Component
@ConfigurationProperties(prefix = "test")
class MyConfig {

  String value; // to map test.value from application.yml
}

使用 JUnit5,我正在尝试测试功能 methodA。但是,我不需要测试 methodB 。因此,我在嘲笑 methodB.

的回应
class ApplicationTests {

  @Mock
  MyConfig myConfig;

  @Mock
  MyUtility myUtility;

  ...

  @Test
  public void testMethodA() {

    Mockito.when(myUtility.methodB()).thenReturn("someValue");
    ...
  }
}

因为我必须模拟 MyUtility,所以我还必须模拟 MyConfig,因为它是一个依赖项(否则 myConfig 显示为 null)。但我不想嘲笑 MyConfig。我希望 methodA 使用 application.yml 文件中存在的值而不是模拟它。

是否可以将 MyConfig 从应用程序上下文注入到 MyUtility 模拟中?

If I could autowire MyConfig into the mocked MyUtility, the code would work fine.

只要您使用 SpringExtension 并正确设置 configuration/context 就可以做到。而不是模拟 MyConfig 将自动装配的配置添加到您的测试 class 并将该配置传递给您创建的 MyUtility class.

The reason I am mocking that specific method is because that method (methodB) is making a network call and returning a response back to methodA. I don't care about the network call.

问题是您目前模拟了 class(不仅是方法)。正如 @PaulBenn 已经提到的,您想使用 @Spy 而不是 @Mock

spy 上的方法调用使用真正的实现,只要您没有为它定义不同的行为。间谍通常是在预先存在的实例上创建的 对象的所有依赖项都应该正常设置。

class ApplicationTests {

    @Mock
    MyConfig myConfig;

    @Test
    public void testMethodA() {

        ...
        MyUtility spy = Mockito.spy(new MyUtility(myConfig));
        Mockito.when(spy.methodB()).thenReturn("someValue");

        spy.methodA();
        ...
    }
}