【问题标题】:SpringBoot junit tests with multiple TomcatServletContainerInitializer 's - BindException: Address already in use"SpringBoot junit 使用多个 TomcatServletContainerInitializer 测试 - BindException:地址已在使用中”
【发布时间】:2016-06-23 18:52:21
【问题描述】:

我有 spring boot 应用程序,如果 ai 单独运行它们,即手动运行,目前我的所有测试都运行绿色,但是当我运行 maven package 命令时,所有测试都以串行模式运行,即彼此之后运行。然后发生的事情是我得到:

"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("开发") 公共类 TomcatEmbededDevelopmentTesting1Profile 扩展 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 {
..
}

【问题讨论】:

  • 你使用的是什么版本的 Spring Boot?
  • TestCase 来自哪里?如果它来自 JUnit 3.8,那么您应该立即删除 extends TestCase,因为您实际上使用的是 JUnit 4.x。
  • @SamBrannen Sam 我正在使用 spring/boot-starter-parent 工件版本 1.3.5.RELEASE。在您发表评论后,我删除了 extends TestCase 指令,但是我仍然得到绑定异常,即地址已在使用中。你有什么其他想法我可以尝试改变吗?
  • 关于还有什么可以尝试的,你看到我的回答了吗?

标签: spring-boot spring-test spring-mvc-test


【解决方案1】:

对于初学者,@Enable* 注释在 Spring Boot 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 以了解有关 Spring Boot 测试支持的更多详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 2015-07-26
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多