【问题标题】:How to bootstrap a test in Spring Boot manually (without @SpringBootTest-Annotation)如何在 Spring Boot 中手动引导测试(没有 @SpringBootTest-Annotation)
【发布时间】:2020-01-04 07:58:45
【问题描述】:

我正在使用Web Flux 将一个项目从Play Framework 迁移到Spring Boot,并且当我手动启动它时它基本上可以运行。但是,我的大多数测试还没有工作。 (我的 play.Application 显然无法注入 org.springframework.beans.factory.BeanFactory,因为没有绑定任何实现。)使用 Play Framework,我曾经在我的测试中创建一个应用程序:

play.Application app = new play.inject.guice.GuiceApplicationBuilder()
    .bindings(
        // here I added a few manual bindings (e.g. mocks)
    ).build();
// Then I could get "beans" out of it:
MyFancyService fancyService = app.injector().instanceOf(MyFancyService.class);
// Or send Http-Requests to it:
Result response = route(app, request);

如何使用 Spring Boot 做到这一点?

我已经尝试/考虑过:

  • @SpringBootTest(SpringBootTest.WebEnvironment.MOCK)@WebFluxTest 注释我的所有测试,并添加@Autowired WebTestClient webClient。但是,尤其是在迁移期间,我宁愿不要过多地更改我的所有测试(上面的代码目前只在 org.junit.Rule 的一个地方)。
  • new SpringBootTestContextBootstrapper().buildTestContext().getApplicationContext() 创建一个ApplicationContext,但不知道如何向它发送请求。

基本上我正在寻找 Spring Boot 中的这三个关键特性(如果可能的话,使用 Web Flux):

  1. 添加/注入一些模拟作为服务(手动添加绑定到 BeanFactory)
  2. 访问一些自动设置的服务(例如app.getInstanceOf(MyFancyService.class)
  3. 发送 Http 请求

【问题讨论】:

  • 第一个子弹是要走的路。
  • 我知道这是个主意,但是我相信您可以以某种方式手动完成,我想知道如何做。 (而且我不想与框架如此紧密地耦合,尤其是在迁移期间,我宁愿不要过多地更改我的所有测试。)
  • 使用框架的重点,就是使用框架。如果您不想太“束缚”,那么您不应该使用框架。然后,您应该自己启动服务并在构建过程中执行测试。部署并从 ansible 开始,使用 bash/python 脚本对服务执行带有 rest 调用的 jar。

标签: java spring spring-boot spring-webflux


【解决方案1】:

我终于或多或少地想通了:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
public class WithApp extends ExternalResource {

    private final WebTestClient webTestClient;

    public WithApp() {
        SpringBootTestContextBootstrapper springBootTestContextBootstrapper = new SpringBootTestContextBootstrapper();
        springBootTestContextBootstrapper.setBootstrapContext(new DefaultBootstrapContext(WithApp.class, new DefaultCacheAwareContextLoaderDelegate()));
        MergedContextConfiguration config = springBootTestContextBootstrapper.buildMergedContextConfiguration();
        ApplicationContext app = new ApplicationContextLoader().loadContext(config);
        MyBean mockedBean = app.getBean(MyBean.class);
        this.webTestClient = WebTestClient.bindToApplicationContext(app).build();
    }

    public WebTestClient.ResponseSpec call(HttpMethod method, String uri, Object body) {
        return webTestClient.method(method).uri(uri).bodyValue(body).exchange();
    }

    @Component
    public static class Config {
        @Primary
        @Bean
        public MyBean getMyBeanForTest() {
            return mock(MyBean.class);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 2019-12-06
    • 2017-06-21
    • 2013-10-12
    • 2022-12-22
    相关资源
    最近更新 更多