猿问

弹簧启动如何测试 Web 服务器初始化事件

我正在尝试测试应用程序向服务注册表注册时发生的应用程序中的功能。仅当应用具有完整的 Web 上下文(即。 位于类路径上,并且 servlet 不会被嘲笑)。这是通过抽象自动服务注册控制的。spring-boot-starter-webspring-cloud-commons


简单测试

所有测试应该做的是以下几点:


1) Bring up Web App

2) Verify auto-registration w/ service registry event fired

3) Manually force close app

4) Verify auto-deregistratoin occurred

方法 1:@SpringBootTest

SpringBootTest使创建完整的Web上下文变得容易,这很棒。但我无法在测试中关闭应用以强制取消注册


@RunWith(SpringRunner.class)

@SpringBootTest(

        classes = MyAutoConfig.class,

        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT

)

@EnableAutoConfiguration

public class DiscoverySpringCloudBootMinimalRegistrationTest {


@Test

public void register_deregister {

    // Force-close app to trigger dereigster (causes exception)

    ((ConfigurableApplicationContext) context).close();


    verify(registry, times(1)).register(autoRegistrationServiceRecord);

    verify(registry, times(1)).deregister(autoRegistrationServiceRecord);

}

调用会导致一个长错误,基本上说不要像这样手动关闭上下文。context.close()


..... contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]] is not active. This may be due to one of the following reasons: 1) the context was closed programmatically by user code; 2) the context was closed during parallel test execution either according to @DirtiesContext semantics or due to automatic eviction from the ContextCache due to a maximum cache size policy.

方法 2:Web上下文运行器

在这种方法中,我避免并手动配置上下文运行器。这非常适合调用,但配置中的 Web 上下文具有模拟 servlet,并且不会触发自动注册所需的内容。@SpringBootTestcontext.close()WebInitializedEvent


public class BasicAutoConfigTests {


    private WebApplicationContextRunner runner;


    @Test

    public void register_deregister() {


       runner = new WebApplicationContextRunner()

              .withConfiguration(

                    AutoConfigurations.of(MyAutoConfig.class));


      });

  }

这几乎有效,但会导致豆子,我推测它未能触发所需的。这种方法如何引导真实、完整的嵌入式 tomcat 服务器?MockServletContextWebServerInitializedEventspring-cloud-commons


慕桂英4014372
浏览 79回答 1
1回答

aluckdog

根据Spencer的建议,我使用弹簧应用程序构建器创建了一个完整的Web应用程序。我也在自动配置模块之外执行此操作 - 在类路径上创建了一个名为“集成测试”的新 maven 子模块。spring-boot-starter-web@Import(MyAutoConfig.class)@SpringBootApplicationpublic class MinStarterBasicApp {@BeanServiceRegistry serviceRegistry() {    return mock(ServiceRegistry.class);    }    static ConfigurableApplicationContext setupWebApp(String... profiles){        System.setProperty("spring.main.allow-bean-definition-overriding", "true");        SpringApplication app = new SpringApplicationBuilder(MinStarterBasicApp.class)                .web(WebApplicationType.SERVLET)                .profiles(profiles)                .build();        return app.run();    }}其中允许我按名称传入应用程序.properties文件,如下所示。此外,请务必确保为每个测试手动提供应用上下文。profilesclosepublic class StarterBasicAutoconfigTest {    ConfigurableApplicationContext context;    @After    public void teardown() {        if (context != null && context.isRunning())            context.close();    }    @Test    public void sometest() {        context = MinStarterBasicApp.setupWebApp("profile1");        ServiceRegistry registry = context.getBean(ServiceRegistry.class);        context.close();        Mockito.verify(registry, times(1)).register(any());        Mockito.verify(registry, times(1)).deregister(any());}
随时随地看视频慕课网APP

相关分类

Java
我要回答