2

我有 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("Development") 公共类 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 {
..
}
4

1 回答 1

4

对于初学者,使用 Spring Boot 1.3.x 的测试类支持@Enable*注释。所以删除那些并将它们移动到实际的类。@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 参考手册以获取有关 Spring Boot 测试支持的更多详细信息。

于 2016-06-23T10:52:21.410 回答