Spring boot 在基于Netty的应用程序中进行单元测试后,SpringApplication未关闭
我有一个很烦人的服务,就是“春天化”。该服务运行良好,可以处理请求/响应 我没有添加单元测试/集成测试。我看到springcontext并没有在测试后关闭。即netty服务器在测试完成后运行。我可以远程登录到该端口,并查看它是否仍然连接到该端口 这是我的SpringBootApp文件Spring boot 在基于Netty的应用程序中进行单元测试后,SpringApplication未关闭,spring-boot,netty,spring-boot-test,Spring Boot,Netty,Spring Boot Test,我有一个很烦人的服务,就是“春天化”。该服务运行良好,可以处理请求/响应 我没有添加单元测试/集成测试。我看到springcontext并没有在测试后关闭。即netty服务器在测试完成后运行。我可以远程登录到该端口,并查看它是否仍然连接到该端口 这是我的SpringBootApp文件 @SpringBootApplication public class NettyService { //Autowired all the required fields //I made t
@SpringBootApplication
public class NettyService {
//Autowired all the required fields
//I made this static so I can access from integration tests to shut it down. I shouldn't need
//this since after each test jvm should be shut-down.
static ChannelFuture serverChannelFuture;
public static void main( String[] args ) {
SpringApplication.run(NettyService.class, args);
}
@PostConstruct
public void start() throws InterruptedException {
serverChannelFuture = bootstrap.bind(tcpSocketAddress).sync();
}
@PreDestroy
public void stop() throws InterruptedException {
serverChannelFuture.channel().closeFuture().sync();
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes=NettyService.class)
public class AppTest
{
@After
public void cleanUp() throws Exception {
//NettyService.serverChannelFuture.channel().closeFuture().sync();
}
@Test
public void contextLoad1() throws Exception
{
assertTrue( true );
}
@Test
public void contextLoad2() throws Exception
{
assertTrue( true );
}
第一次测试时,它通过得很好。但第二次测试失败,出现“地址正在使用”错误。
第一次测试完成后,Netty没有拆掉。我希望spring上下文在测试结束或至少jvm退出时关闭
注意,我已经注释掉了cleanUp()方法中的行。如果我取消注释,即使第一个测试也不会运行。它只是永远挂着。你不正确地关闭了Netty 这只是等待服务器通道关闭,但它从未请求它实际关闭,这将永远阻塞 不要调用
.closeFuture()
(将来的事件),而是调用.close()
(立即关闭它)
如果您还使用新的
NioEventLoopGoup
实例创建线程池,请确保在关闭通道后调用其关闭功能来终止线程池。您正在错误地关闭Netty
这只是等待服务器通道关闭,但它从未请求它实际关闭,这将永远阻塞
不要调用.closeFuture()
(将来的事件),而是调用.close()
(立即关闭它)
如果还使用
NioEventLoopGoup
的新实例创建线程池,请确保在关闭通道后调用其shutdown函数来终止该操作。除非您使用@DirtiesContext
,否则它不会在测试之间重新启动,否则它将启动一次并重新使用。应用程序不应该在测试结束时关闭吗?我运行了一个测试,在测试通过后,它仍然永远挂在那里,我可以在端口上ping服务器如果您运行多个测试类(一个@test
方法是测试,而不是在我的测试定义中定义的类),它将保持启动状态,直到最后一个类的最后一个测试方法运行为止。如果您在这里只运行这个类,那么有两个测试,在两个方法都执行之后,它应该关闭。如果这种情况没有发生,那就与您的设置有关,这可能是因为您正在管理自己的Netty,而不是让Spring Boot控制生命周期。我让Spring Boot管理Netty。由于它没有关闭,我尝试在cleanUp()中强制关闭,这也没有帮助。您没有让Spring Boot管理Netty,因为您的Spring Boot应用程序中有@PreDestroy
和@PostConstruct
。这意味着您实际上是在控制Netty实例,而不是Spring启动。除非您使用@DirtiesContext
,否则它不会在测试之间重新启动,但它会启动一次并重新使用。应用程序不应该在测试结束时关闭吗?我运行了一个测试,在测试通过后,它仍然永远挂在那里,我可以在端口上ping服务器如果您运行多个测试类(一个@test
方法是测试,而不是在我的测试定义中定义的类),它将保持启动状态,直到最后一个类的最后一个测试方法运行为止。如果您在这里只运行这个类,那么有两个测试,在两个方法都执行之后,它应该关闭。如果这种情况没有发生,那就与您的设置有关,这可能是因为您正在管理自己的Netty,而不是让Spring Boot控制生命周期。我让Spring Boot管理Netty。由于它没有关闭,我尝试在cleanUp()中强制关闭,这也没有帮助。您没有让Spring Boot管理Netty,因为您的Spring Boot应用程序中有@PreDestroy
和@PostConstruct
。这意味着您实际上是在控制Netty实例,而不是Spring Boot。
@PreDestroy
public void stop() throws InterruptedException {
serverChannelFuture.channel().closeFuture().sync();
}
@PreDestroy
public void stop() throws InterruptedException {
serverChannelFuture.channel().close().sync();
}