2016-06-14 150 views
1

我有春季启动应用程序,目前我的所有测试都运行绿色,如果AI分别运行它们,即手动,但是当我运行Maven包命令,然后所有。在后对方即串行模式试运行,然后会发生什么事是,我得到:SpringBoot junit测试多个TomcatServletContainerInitializer的 - BindException:地址已经在使用“

"java.net.BindException: Address already in use". 

基本上是因为测试串行地运行他们都试图声称插座127.0.0.1:8081而且,由于该插座处于 TIME_WAIT状态,第二个测试无法声明该插座。即netstat的输出-apn

netstat的-apn | grep的-i 8080

tcp 0  0 127.0.0.1:8080   127.0.0.1:33952   TIME_WAIT 
  • 现在我有两个不同的配置文件配置即开发和生产,即见下文:

    @Configuration @profile( “发展”) public class TomcatEmbededDevelopmentTesting1Profile extends SpringServletContainerInitializer {...}

    @Configuration @Profile(“Production”)公共类 TomcatEmbededProductionProfile扩展 SpringServletContainerInitializer {..}

我寻找后,现在是指定哪些客户TomcatServletContainerInitializer我可以运行一个特点,即我将拥有5种不同的一个都不同端口上侦听/插座。 问题是如果我有5个不同的TomcatEmbeded配置类都标有“@Profile(”Development“)”,那么我该如何告诉junit执行我需要的配置类。我已经厌倦了使用@SpringApplicationConfiguration,但那不会飞。

@SpringApplicationConfiguration(classes = { 
     ... 
     TomcatEmbededDevelopmentTesting1Profile.class, 
     ... 
     }) 

然后我发现,说明有一些神奇的注释@IntegrationTest(“server.port:0”)网的一篇文章这是假设随机端口,但没有工作对我来说好。 什么是在春季做正确的方法?任何提示都非常感谢。

这里就是比如我测试的:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners(listeners={ ServletTestExecutionListener.class, 
            DependencyInjectionTestExecutionListener.class, 
            DirtiesContextTestExecutionListener.class, 
            WithSecurityContextTestExecutionListener.class 
            } 
     ) 

@SpringApplicationConfiguration(classes = { 
     SecurityWebApplicationInitializerDevelopment.class, 
     SecurityConfigDevelopment.class, 
     TomcatEmbededDevelopmentTesting1Profile.class, 
     Internationalization.class, 
     MVCConfigDevelopment.class, 
     PersistenceConfigDevelopment.class, 
     ServerAuthenticationSuccessHandler.class, 
     ServerRedirectAuthenticationSuccessHandler.class, 
     LogicServiceRegistryPostProcessor.class 
     }) 
@WebAppConfiguration 
@EnableWebSecurity 
@EnableWebSocket 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
//@IntegrationTest({"server.port=0", "management.port=0"}) 
@ActiveProfiles("Development") 
    public class quickTest extends TestCase { 
.. 
} 
+0

您使用的是什么版本的Spring Boot? –

+0

'TestCase'从哪里来?如果它来自JUnit 3.8,那么您应该立即删除'extends TestCase',因为您实际上正在使用JUnit 4.x. –

+0

@ SamBrannen Sam我使用的是spring/boot-starter-parent工件版本1.3.5.RELEASE。在你的评论之后,我已经删除了扩展的TestCase指令,但是我仍然得到那个绑定异常,即已经在使用的地址。你有什么想法可以尝试改变吗? – Tito

回答

3

对于初学者来说,@Enable*注解使用Spring引导1.3.x的支持测试类所以删除它们并将它们移到实际的@Configuration类。其次,向@SpringApplicationConfiguration提供大量的课程列表是最糟糕的做法。最佳做法是为集成测试定义一个@Configuration类,其中使用@Import来包含您需要的任何其他配置类。

三,使用@WebIntegrationTest(randomPort = true)代替@WebAppConfiguration

四,不扩展TestCase:这是JUnit 4,而不是JUnit 3。

五,不包括ServletTestExecutionListener:它仅用于外的容器集成测试,以及你正在做的是在容器集成测试(即在嵌入式Tomcat servlet容器)。

第六,如果您需要随机端口号,只需通过@Value("${local.server.port}")注入它。

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners(
    listeners = WithSecurityContextTestExecutionListener.class, 
    mergeMode = MERGE_WITH_DEFAULTS 
) 
@SpringApplicationConfiguration({ 
     SecurityWebApplicationInitializerDevelopment.class, 
     SecurityConfigDevelopment.class, 
     TomcatEmbededDevelopmentTesting1Profile.class, 
     Internationalization.class, 
     MVCConfigDevelopment.class, 
     PersistenceConfigDevelopment.class, 
     ServerAuthenticationSuccessHandler.class, 
     ServerRedirectAuthenticationSuccessHandler.class, 
     LogicServiceRegistryPostProcessor.class 
     }) 
@WebIntegrationTest(randomPort = true) 
@ActiveProfiles("Development") 
public class QuickTest { 

    @Value("${local.server.port}") 
    int port; 

    // ... 
} 

所以,看看有没有什么让你任何进一步的,并在春季启动的测试支持读取Spring Boot Reference Manual进一步的细节。