Netty Unit Test Solution

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!
 

Tags: Java

Posted by killfall on Mon, 18 Apr 2022 01:42:25 +0930