首页 > 解决方案 > 如何在 Junit 5 *before* Spring 测试上下文加载之前获取回调?

问题描述

在运行任何测试之前,我正在使用 Junit 5 扩展来启动 Wiremock 服务器。但是,Spring 上下文中的一个 bean 将远程调用作为其初始化的一部分,我无法更改,并且该调用会导致 ConnectionException,因为 Wiremock 服务器尚未启动。

如何在Spring 加载文本上下文之前配置我的 JUnit 5 测试以获取回调?

我的 JUnit 5 扩展如下所示:

public class MyWiremockExtension implements BeforeAllCallback, AfterAllCallback {

  private final WireMockServer wireMock = new WireMockServer(...);
  
  @Override
  public void beforeAll(ExtensionContext extensionContext) throws Exception {
    wireMock.start();
  }

  @Override
  public void afterAll(ExtensionContext extensionContext) throws Exception {
    wireMock.stop();
  }
}

Spring Bean 配置深埋在我的 OkHttpClient bean 所依赖的上游代码中,但它看起来像这样:

@Configuration
public class OkHttpClientConfiguration {

  @Bean
  OkHttpClient okHttpClient(...) {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()...build();
    // wrap the okHttpClient in OAuth handling code which eagerly fetches a token
  }
}

我的测试如下所示:

@SpringBootTest(properties = {...})
@ExtendWith(MyWiremockExtension.class)
class MyTest {
...
}

到目前为止,我找到的最接近的答案是How to register Spring Context Events for current test ApplicationContext at runtime ,但这并没有在测试上下文加载之前提供回调方法。

我对如何做到这一点的最佳猜测是:

  1. 创建我自己的ContextCustomizerFactory,或
  2. extend SpringBootTestContextBootstrapper,覆盖buildTestContext()在调用之前启动wiremock super.buildTestContext(),然后@BootstrapWith是我的类而不是Spring Boot的类,尽管我不确定我会使用哪个回调来停止wiremock服务器。

标签: javaspringspring-bootjunit5

解决方案


这对我有用:

  • 使用 Spring TestContext 框架实现它,这也使它与 TestNG 一起工作
  • 实施TestExecutionListener
  • 使测试执行监听器实现Ordered
  • 实现getOrder并返回小于 2000 的值(DependencyInjectionTestExecutionListener 的顺序)

示例代码https://github.com/marschall/spring-test-scope/blob/master/src/main/java/com/github/marschall/spring/test/scope/TestScopeTestExecutionListener.java


推荐阅读