Share Netty Unit Test Solutions Today
A special
Channel
Realization-
EmbeddedChannel
, it is
Netty
Provided specifically for unit testing of ChannelHandler by needle insertion. Write inbound or outbound data to EmbeddedChannel
, and then check if anything has arrived at ChannelPipeline
End of. In this way, you can determine if the message has been encoded or decoded and whether any ChannelHandler has been triggered
Action.
writeInbound(Object... msgs)
Write inbound messages to
EmbeddedChannel
Medium.
If
By
readInbound()
Method reads data from EmbeddedChannel and returns
true
readInbound()
from
EmbeddedChannel
Read an inbound message. Anything returned traverses the entire Channel Pipeline.
If
If there is nothing to read, return
null
writeOutbound(Object... msgs)
Write outbound messages to
EmbeddedChannel
Medium.
If
Now you can
readOutbound()
Method reads something from EmbeddedChannel and returns
true
readOutbound()
from
EmbeddedChannel
Read an outbound message. Anything returned traverses the entire Channel Pipeline. If there is nothing to read, return
null
finish()
take
EmbeddedChannel
Marked as complete and returns true if there is readable inbound or outbound data
. This method will also be called
EmbeddedChannel
On
close()
Method. Inbound data from ChannelInboundHandler
Processing, representing data read from a remote node. Outbound data is processed by ChannelOutboundHandler and represents the data that will be written to the remote node. Use writeOutbound()
Method writes a message to
Channel
And pass
ChannelPipeline
Pass in the direction of the outbound station. You can then use readOutbound()
Method reads processed messages to determine if the results are as expected. Similarly, for inbound data, you need to use writeInbound()
and
readInbound()
Method. In each case, the message will be delivered through ChannelPipeline
And is either associated with ChannelInboundHandler or
ChannelOutboundHandler
Handle.

1. Test Inbound Messages
We have a simple
ByteToMessageDecoder
Realization. Given enough data, this implementation will produce frames of fixed size. If there is not enough data to read, it will wait for the next data block to arrive and will check again whether a new frame can be generated. This particular decoder will produce a fixed 3
Byte-sized frames. Therefore, it may require multiple events to provide enough bytes to produce one frame.
Test class:
public class FixedLengthFrameDecoderTest { @Test public void testFramesDecoded() { //Create a ByteBuf and store 9 bytes ByteBuf buf = Unpooled.buffer(); for (int i = 0; i < 9; i++) { buf.writeByte(i); } ByteBuf input = buf.duplicate(); EmbeddedChannel channel = new EmbeddedChannel( new FixedLengthFrameDecoder(3) ); /*Return false*/ System.out.println("For the first time:"+input.readBytes(1)); assertFalse(channel.writeInbound(input.readBytes(1))); assertFalse(channel.writeInbound(input.readBytes(1))); assertTrue(channel.writeInbound(input.readBytes(1))); assertTrue(channel.writeInbound(input.readBytes(6))); channel.finish(); // read messages //Read the generated message and verify if there are 3 frames (slices), each of which is 3 bytes ByteBuf read = (ByteBuf) channel.readInbound(); //Compare with Source assertEquals(buf.readSlice(3), read); read.release(); read = (ByteBuf) channel.readInbound(); assertEquals(buf.readSlice(3), read); read.release(); read = (ByteBuf) channel.readInbound(); assertEquals(buf.readSlice(3), read); read.release(); assertNull(channel.readInbound()); buf.release(); } }
2. Test Outbound Messages
Processor under test -
AbsIntegerEncoder
, it is
Netty
Of
MessageToMessageEncoder
An implementation of specialization for converting negative integers to absolute values.
The example will work as follows:Hold AbsIntegerEncoder
Of
EmbeddedChannel
Will be
4
Write outbound data as a negative integer of bytes;
Encoder will be passed in from
ByteBuf
Reads each negative integer and calls it
Math.abs()
Method to get its absolute value;
The encoder will write the absolute value of each negative integer to
ChannelPipeline
Medium.

Test class:
public class AbsIntegerEncoderTest { @Test public void testEncoded() { //(1) Create a ByteBuf and write nine negative integers ByteBuf buf = Unpooled.buffer(); for (int i = 1; i < 10; i++) { buf.writeInt(i * -1); } //(2) Create an EmbeddedChannel and install an AbsIntegerEncoder to test EmbeddedChannel channel = new EmbeddedChannel( new AbsIntegerEncoder()); //(3) Write ByteBuf and assert that calling readOutbound() will produce data assertTrue(channel.writeOutbound(buf)); //(4) Mark the Channel as complete assertTrue(channel.finish()); // read bytes //(5) Read the resulting messages and assert that they contain corresponding absolute values for (int i = 1; i < 10; i++) { int x = channel.readOutbound(); assertEquals(i, x); } assertNull(channel.readOutbound()); } }
Test results:
3. Test exception handling
Applications often need to perform more complex tasks than converting data. For example, you may need to handle malformed inputs or excessive data. In the next example, if the number of bytes read exceeds a certain limit, we will throw a TooLongFrameException
. This is often used to prevent resources from being exhausted. Set maximum frame size to 3
Bytes. If the size of a frame exceeds this limit, the program will discard its bytes and throw a TooLongFrameException. In ChannelPipeline
Other in
ChannelHandler
You can choose to handle the exception in the exceptionCaught() method or ignore it.

Test class:
public class FrameChunkDecoderTest { @Test public void testFramesDecoded() { //Create a ByteBuf and write 9 bytes to it ByteBuf buf = Unpooled.buffer(); for (int i = 0; i < 9; i++) { buf.writeByte(i); } ByteBuf input = buf.duplicate(); //Create an EmbeddedChannel and install it to allow a frame up to 3 bytes // FrameChunkDecoder EmbeddedChannel channel = new EmbeddedChannel( new FrameChunkDecoder(3)); //Write 2 bytes to it and assert that they will produce a new frame assertTrue(channel.writeInbound(input.readBytes(2))); try { //Write a 4-byte frame and capture the expected TooLongFrameException channel.writeInbound(input.readBytes(4)); } catch (TooLongFrameException e) { e.printStackTrace(); } //Write the remaining 2 bytes and assert that a valid frame will be generated assertTrue(channel.writeInbound(input.readBytes(3))); //Mark the Channel as Completed assertTrue(channel.finish()); } }
Execution result: throw exception, resize to continue testing
Now that Netty unit tests have been shared, they can be tested and used in the project. Please look forward to sharing the next Netty-related UDP protocol!