繁体   English   中英

Spring Boot测试应用程序Yaml java.lang.IllegalStateException:Tomcat连接器处于失败状态

[英]Spring Boot Testing Application Yaml java.lang.IllegalStateException: Tomcat connector in failed state

我是测试Spring应用程序的新手,不确定如何在Spring Boot应用程序中测试定义为application.yml的应用程序配置文件。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {WebApplication.class})
@WebAppConfiguration

public class ApplicationSettingsTest {
    @Test
    public void applicationPicksRightTeamProfile() throws Exception {
        WebApplication.main(new String[] { "--spring.profiles.active=FalconDev1" });
        String output = this.outputCapture.toString();
        assertThat(output, containsString("falcondev.io"));
    }

    @Test
    public void applicationPicksRightDefaultProfile() throws Exception {
        WebApplication.main(new String[0]);
        String output = this.outputCapture.toString();
        assertThat(output, containsString("defaultdev.io"));
    }
}

我的第一个测试似乎通过了,但是第二个测试失败了,并出现多个错误,

org.apache.catalina.LifecycleException:无法启动组件[Connector [org.apache.coyote.http11.Http11NioProtocol-8090]]

由以下原因引起:org.apache.catalina.LifecycleException:service.getName():“ Tomcat”; 协议处理程序启动失败,发生在org.apache.catalina.connector.Connector.startInternal(Connector.java:1014)〜[tomcat-embed-core-7.0.59.jar:7.0.59]

引起原因:java.net.BindException:sun.nio.ch.Net.bind(本机方法)〜[na:1.6.0_65]处已经在使用的地址org.springframework.boot.context.embedded.EmbeddedServletContainerException:无法启动org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:165)处的嵌入式Tomcat servlet容器。原因:java.lang.IllegalStateException:Tomcat连接器在org.springframework.boot.context处处于失败状态。 Embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:159)〜[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]

编辑: application.yml

server:
    port: ${port:8090}

我确实知道应用程序实际上已经在端口8090上启动,而我第二次尝试在同一端口上再次运行,这是我不希望的。

因此,如何在测试中告诉您仅加载应用程序上下文而不是启动实际应用程序。

以下代码将使用随机端口运行spring boot嵌入式容器:

@IntegrationTest("server.port:0") 

为了在测试中设置Spring活动配置文件,您可以使用ActiveProfiles注释。

@ActiveProfiles("test")

在应用程序属性中或使用--spring.profiles.active=test通过环境变量设置spring.profiles.active

Spring包含Environment bean。 如果要在代码中获取配置文件,可以使用以下代码:

@Autowired
Environment environment;

String[] profiles = environment.getActiveProfiles();

下面的代码WebApplication.main(new String[0]); 是不正确的。 您实际上确实在运行2 Spring上下文。

听到的问题是,您首先使用指令WebApplication.main(....);来控制Spring上下文WebApplication.main(....);

关键的一点是,测试类会断言您具有测试上下文,在此阶段,这将是用于测试的Spring上下文,因此您无需启动嵌入式tomcat。我建议不要使用@WebIntegrationTest而使用@WebAppConfiguration

对于第一种测试方法,您将有一个Spring上下文进行测试,然后启动另一个spring竞赛,该竞赛也将tomcat启动到8090端口,此后,第二种测试方法继承了该测试上下文,但是在您重新启动该测试方法中上下文和同一端口上的另一个tomcat,在此阶段,您将获得异常。

@IntegrationTest("server.port:0")不起作用,因为此注释在测试上下文中起作用,而不是在您以heands开始的上下文中起作用。

我的建议是以这种方式重构您的代码:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {WebApplication.class})
@WebIntegrationTest(randomPort = true)
@ActiveProfiles("FalconDev1")
public class ApplicationSettingsTest {

    @Test
    public void applicationPicksRightTeamProfile() throws Exception {

        String output = this.outputCapture.toString();
        assertThat(output, containsString("falcondev.io"));
    } 
}

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {WebApplication.class})
@WebIntegrationTest(randomPort = true)
public class ApplicationSettingsTest {

    @Test
    public void applicationPicksRightDefaultProfile() throws Exception {
        String output = this.outputCapture.toString();
        assertThat(output, containsString("defaultdev.io"));
    }
}

两个测试类映射了您的两个测试类别,第一个可以与默认配置隔离地测试配置文件FalconDev1 ,第二个可以测试另一个配置文件。 通过这种方式,您可以受益于Spring抽象。

我希望这可以帮助您

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM