Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test netty handler

I implement a handler which extends SimpleChannelHandler, and overrides some methods such as channelConnected, messageReceived. However, I am wondering how to unit test it?

I searched about "netty unit test" and found one article which said considering CodecEmbedder, but I am still not sure how to begin. Do you have any example or advice on how to unit test Netty code?

Thanks a lot.

like image 769
zhquake Avatar asked Oct 11 '13 07:10

zhquake


1 Answers

In Netty, there are different ways to test your networking stack.

Testing ChannelHandlers

You can use Netty's EmbeddedChannel to mock a netty connection for testing, an example of this would be:

@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);
}

This test above tests for StringDecoder ability to decode unicode correct (example from this bug posted by me)

You can also test the encoder direction using EmbeddedChannel, for this you should use writeOutBound and readInbound.

More Examples:

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.

ByteBuf

To test if you use your bytebufs, you can set a JVM parameter that checks for leaked ByteBuf, for this, you should add -Dio.netty.leakDetectionLevel=PARANOID to the startup parameters, or call the method ResourceLeakDetector.setLevel(PARANOID).

like image 74
Ferrybig Avatar answered Oct 18 '22 01:10

Ferrybig