Netty笔记(九) 单元测试

    Netty提供了EmbeddedChannel,来建立内嵌的通道, 其并不与网络设置进行真正通信,适合我们来进行对ChannelHandler逻辑的单元测试。

    EmbeddedChannel 的父类 AbstractEmbeddedChannel 提供以下方法:

writeInbound(..) : 将信息写入Channel, ChannelInboundHandler的实现将响应事件,写入成功返回true

readInbound(..)    : 读取通过writeInbound()写入 Channel的数据,如果返回null,则无数据。

writeOutbound()    : 将信息写入Channel , ChannelOutboundHandler的实现奖响应事件,写入成功返true

readOutbound() : 读取writeOutbound()写入Channel的数据。

finish()    :返回true表示,写入Channel的数据已经完成。

关系图:

Netty笔记(九) 单元测试


Codes 是 ChannlHandler的实现,下面些测试Decoding 跟 Encoding,分别对应Inbound跟Outbound

测试Inbound

FixedLengthFrameDecoder

public class FixedLengthFrameDecoder extends ByteToMessageDecoder
{

    private final int frameLength;

    public FixedLengthFrameDecoder( int frameLength )
    {
        if ( frameLength <= 0 )
        {
            throw new IllegalArgumentException( "frameLength must be a positive integer:" + frameLength );
        }
        this.frameLength = frameLength;
    }

    @Override
    protected void decode( ChannelHandlerContext ctx, ByteBuf in, List<Object> out ) throws Exception
    {
        while ( in.readableBytes() >= frameLength )
        {
            ByteBuf buf = in.readBytes( frameLength );
            out.add( buf );
        }
    }

}
FixedLengthFrameDecoderTest

public class FixedLengthFrameDecoderTest
{
    @Test
    public void testFramesDecoded() {
        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));
        Assert.assertFalse(channel.writeInbound(input.readBytes(2)));
        Assert.assertTrue(channel.writeInbound(input.readBytes(7)));

        Assert.assertTrue(channel.finish());
        Assert.assertEquals(buf.readBytes(3), channel.readInbound());
        Assert.assertEquals(buf.readBytes(3), channel.readInbound());
        Assert.assertEquals(buf.readBytes(3), channel.readInbound());
    }
}

测试Outbond

AbsIntegerEncoder

public class AbsIntegerEncoder extends MessageToByteEncoder<ByteBuf>
{
    @Override
    protected void encode( ChannelHandlerContext ctx, ByteBuf in, ByteBuf out ) throws Exception
    {
        while ( in.readableBytes() >= 4 )
        {
            int value = Math.abs( in.readInt() );
            out.writeInt( value );
            System.out.println( "encoded value:" + value );
        }
    }
}
AbsIntegerEncoderTest

public class AbsIntegerEncoderTest
{
    @Test
    public void testEncoded() throws Exception
    {
        ByteBuf buf = Unpooled.buffer();
        for ( int i = 0; i < 10; i++ )
        {
            buf.writeInt( i * -1 );
        }
        
        EmbeddedChannel channel = new EmbeddedChannel( new AbsIntegerEncoder() );
        Assert.assertTrue( channel.writeOutbound( buf ) );
        Assert.assertTrue( channel.finish() );
        ByteBuf output = (ByteBuf) channel.readOutbound();
        
        for ( int i = 0; i < 10; i++ )
        {
            Assert.assertEquals( i, output.readInt() );
        }
        
        Assert.assertFalse( output.isReadable() );
        Assert.assertNull( channel.readOutbound() );
    }
}
测试异常

FrameChunkDecoder

public class FrameChunkDecoder extends ByteToMessageDecoder
{

    private final int maxFrameSize;

    public FrameChunkDecoder( int maxFrameSize )
    {
        this.maxFrameSize = maxFrameSize;
    }

    @Override
    protected void decode( ChannelHandlerContext ctx, ByteBuf in, List<Object> out ) throws Exception
    {
        int readableBytes = in.readableBytes();
        if ( readableBytes > maxFrameSize )
        {
            in.clear();
            throw new TooLongFrameException();
        }

        ByteBuf buf = in.readBytes( readableBytes );
        out.add( buf );
    }
}



FrameChunkDecoderTest

public class FrameChunkDecoderTest
{

    @Test
    public void testFramesDecoded() throws Exception
    {
        ByteBuf buf = Unpooled.buffer();
        for ( int i = 0; i < 10; i++ )
        {
            buf.writeByte( i );
        }

        ByteBuf input = buf.duplicate();
        EmbeddedChannel channel = new EmbeddedChannel( new FrameChunkDecoder( 3 ) );

        Assert.assertTrue( channel.writeInbound( input.readBytes( 2 ) ) );

        try
        {
            channel.writeInbound( input.readBytes( 4 ) );
            Assert.fail();
        }
        catch ( TooLongFrameException e )
        {
        }

        Assert.assertTrue( channel.writeInbound( input.readBytes( 3 ) ) );
        Assert.assertTrue( channel.finish() );

        Assert.assertEquals( buf.readBytes( 2 ), channel.readInbound() );
        Assert.assertEquals( buf.skipBytes( 4 ).readBytes( 3 ), channel.readInbound() );

    }
}



你可能感兴趣的:(Netty笔记(九) 单元测试)