【问题标题】:How to inject from application context into a mock in Junit5 Mockito?如何从应用程序上下文注入 Junit5 Mockito 中的模拟?
【发布时间】:2019-12-10 08:49:12
【问题描述】:

我必须在我的 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 模拟?

【问题讨论】:

  • 嗨,你为什么要嘲笑你的Utility 班级?如果它是你正在测试的类,它不应该被嘲笑,对吧?看来您可能需要@Spy
  • 我正在尝试测试实用程序类的methodA。但我不想测试由methodA 在内部调用的methodBmethodB 发出 Http 请求。我想模拟methodB的响应以避免网络调用,只是测试methodA的功能
  • 要拦截对methodB的方法调用,您需要某种代理,例如一个 Mockito 间谍。如果您想模拟您通过 HTTP 调用的远程服务器,WireMock 也可能很有用。如果您需要在 Spring 上下文中替换 bean,@MockBean 可能会帮助您
  • 但是没有办法在模拟中自动装配?因此,如果一个 mock 正在使用任何其他依赖项,我们也必须模拟它们?
  • 如果您在模拟 MyUtility,则无需模拟 MyConfig,因为实现不再重要。为什么要模拟该特定方法?似乎您在错误的级别上解决了这个问题。

标签: java spring-boot unit-testing mockito junit5


【解决方案1】:

如果我可以将 MyConfig 自动连接到模拟的 MyUtility 中,代码就可以正常工作。

只要您使用SpringExtension 并正确设置您的配置/上下文,您就可以做到这一点。不要模拟MyConfig,而是将自动装配的配置添加到您的测试类中,并将该配置传递给您创建的MyUtility 类。

我嘲笑该特定方法的原因是该方法(methodB)正在进行网络调用并将响应返回给methodA。我不关心网络调用。

问题是您当前模拟了类(而不仅仅是方法)。正如@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();
        ...
    }
}

【讨论】:

  • 谢谢。这应该可以解决问题。我不太确定之前嘲笑间谍的事情。
猜你喜欢
  • 2016-03-07
  • 2017-11-02
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多