【问题标题】:How to unit test netty handler如何对 netty 处理程序进行单元测试
【发布时间】:2013-10-11 07:13:45
【问题描述】:

我实现了一个扩展 SimpleChannelHandler 的处理程序,并覆盖了一些方法,例如 channelConnected、messageReceived。但是,我想知道如何对其进行单元测试?

我搜索了“netty unit test”并找到了one article,它说考虑了CodecEmbedder,但我仍然不知道如何开始。你有关于如何对 Netty 代码进行单元测试的示例或建议吗?

非常感谢。

【问题讨论】:

    标签: unit-testing netty


    【解决方案1】:

    在 Netty 中,有多种方法可以测试您的网络堆栈。

    测试 ChannelHandlers

    您可以使用 Netty 的 EmbeddedChannel 模拟 netty 连接进行测试,例如:

    @Test
    public void nettyTest() {
        EmbeddedChannel channel = new EmbeddedChannel(new StringDecoder(StandardCharsets.UTF_8));
        channel.writeInbound(Unpooled.wrappedBuffer(new byte[]{(byte)0xE2,(byte)0x98,(byte)0xA2}));
        String myObject = channel.readInbound();
        // Perform checks on your object
        assertEquals("☢", myObject);
    }
    

    上述测试测试 StringDecoder 是否能够正确解码 unicode (example from this bug posted by me)

    您还可以使用EmbeddedChannel 测试编码器方向,为此您应该使用writeOutBoundreadInbound

    更多示例:

    DelimiterBasedFrameDecoderTest.java:

    @Test
    public void testIncompleteLinesStrippedDelimiters() {
        EmbeddedChannel ch = new EmbeddedChannel(new DelimiterBasedFrameDecoder(8192, true,
                Delimiters.lineDelimiter()));
        ch.writeInbound(Unpooled.copiedBuffer("Test", Charset.defaultCharset()));
        assertNull(ch.readInbound());
        ch.writeInbound(Unpooled.copiedBuffer("Line\r\ng\r\n", Charset.defaultCharset()));
        assertEquals("TestLine", releaseLater((ByteBuf) ch.readInbound()).toString(Charset.defaultCharset()));
        assertEquals("g", releaseLater((ByteBuf) ch.readInbound()).toString(Charset.defaultCharset()));
        assertNull(ch.readInbound());
        ch.finish();
    }
    

    More examples on github.

    字节缓冲区

    要测试你是否使用bytebufs,你可以设置一个JVM参数来检查泄漏的ByteBuf,为此你应该在启动参数中添加-Dio.netty.leakDetectionLevel=PARANOID,或者调用方法ResourceLeakDetector.setLevel(PARANOID)

    【讨论】:

    • 我花了一点时间才理解它,但我成功了。我只是用我的 ChannelHandler 替换了 EmbeddedChannel 的构造函数中的参数。你有没有找到不重复这么多代码的方法?我的意思是... channel = new EmbeddedChannel(new MessageHandler1());通道 = 新 EmbeddedChannel(new MessageHandler2());等等……
    • 谢谢!我使用 Netty 已经有一段时间了,除了设置服务器之外,我从来不知道如何测试我的处理程序逻辑!这将节省我很多时间!!!!!!!!!!
    • @Ferrybig 您展示的测试和 github 链接上的一些示例是有意义的,因为您正在测试特定的网络协议或特定规则。执行一些其他业务逻辑操作的处理程序呢?就像我有一个具有验证用户的 authService 的 AuthHandler 一样。我有 authService 的 UT,但实际上 channelReadComplete 只是调用 authService.validate(user)。那些可测试的场景仍然存在吗?
    • 在使用ResourceLeakDetector.setLevel(PARANOID) 时,您如何建议我们通过或不通过测试?
    • @Ferrybig 帮了我大忙。谢谢!!
    猜你喜欢
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 2013-10-24
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多