在基于Netty的应用程序中进行单元测试后,SpringApplication没有关闭

时间:2019-04-26 07:03:42

标签: spring-boot netty spring-boot-test

我有一个“弹性化”的Netty服务。该服务运行良好,可以处理请求/响应。

我没有添加单元测试/集成测试。我看到测试后springcontext没有关闭。即测试完成后,netty服务器正在运行。我可以通过telnet连接到该端口,然后查看该端口仍与之连接

这是我的SpringBootApp文件

@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()方法中注释掉了这一行。如果我没有评论,那么即使第一个测试也不会运行。它只是永远挂着。

1 个答案:

答案 0 :(得分:2)

您错误地关闭了Netty。

@PreDestroy
public void stop() throws InterruptedException {
    serverChannelFuture.channel().closeFuture().sync();
}

这只是在等待服务器通道关闭,但是从不要求它实际关闭,这将永远阻塞。

呼叫.closeFuture()(立即关闭),而不是呼叫.close()(将来发生的事件)。

@PreDestroy
public void stop() throws InterruptedException {
    serverChannelFuture.channel().close().sync();
}

如果您还使用NioEventLoopGoup的新实例创建线程池,请确保在关闭通道后也通过调用其关闭函数来终止该线程池。