Netty 使用 EmbeddedChannel 进行单元测试

版权声明:转载随意,附上转载信息即可 :) https://blog.csdn.net/Al_assad/article/details/79472347

Netty 使用 EmbeddedChannel 进行单元测试


对于 Netty 的 ChannelHandler 进行单元测试,Netty 提供了 EmbeddedChannel 嵌入式通道来完成这一过程,主要使用该通道来测试数据的入站出站过程是否合法;
该通道提供以下常用的 API:
writeInbound 写一个入站消息到 EmbeddedChannel。 如果数据能从 EmbeddedChannel 通过 readInbound() 读到,则返回 true;
readInbound 从 EmbeddedChannel 读到入站消息。任何返回遍历整个ChannelPipeline。如果读取还没有准备,则此方法返回 null;
writeOutbound 写一个出站消息到 EmbeddedChannel。 如果数据能从 EmbeddedChannel 通过 readOutbound() 读到,则返回 true;
readOutbound 从 EmbeddedChannel 读到出站消息。任何返回遍历整个ChannelPipeline。如果读取还没有准备,则此方法返回 null;
Finish 如果从入站或者出站中能读到数据,标记 EmbeddedChannel 完成并且返回。这同时会调用 EmbeddedChannel 的关闭方法;
完整 API 见: http://netty.io/4.1/api/io/netty/channel/embedded/EmbeddedChannel.html

以下图示了 ChannelPipeline 使用 EmbeddedChannel 的方法:



入站处理器测试

以下测试一个入站解码器 FixedLengthFrameDecoder;
FixedLengthFrameDecoder
 
//用于进行测试的 Decoder,将读取的帧分隔为固定长度
public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
    private final int frameLength;   //帧长度
    public FixedLengthFrameDecoder(int frameLength) {
        this.frameLength = frameLength;
    }
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        //帧分割
        while(in.readableBytes() >= frameLength)
            out.add(in.readBytes(frameLength));
    }
}
测试代码:
 
 @Test
    public void testFixedFrameDecoder(){
        EmbeddedChannel channel = new EmbeddedChannel(new FixedLengthFrameDecoder(4));
        //测试入站写入
        ByteBuf buf = Unpooled.buffer();
        for(int i = 0; i < 10 ; i++)
            buf.writeByte(i);
        ByteBuf in = buf.duplicate();
        //入站写入3个字节,此时 Decoder 会缓存这些数据,并没有转发这些数据到下一个 ChannelHandler
        assertFalse(channel.writeInbound(in.readBytes(3)));
        //入站写入7个字节,加上之前写入的3个字节,Decoder 转发其中前8个字节,分为2组转发给下一个 ChannelHandler,剩余2个字节仍被缓存
        assertTrue(channel.writeInbound(in.readBytes(7)));
        assertTrue(channel.finish());  //向通道发送结束信号
        //测试入站读取
        //由上面的写入过程可以估计,前2次都可以读取到值,第3次读取为空值
        ByteBuf read = channel.readInbound();
        assertEquals(read,buf.readSlice(4));
        read.release();
        read = channel.readInbound();
        assertEquals(read,buf.readSlice(4));
        read.release();
        read = channel.readInbound();
        assertNull(read);
    }

出站处理器测试

以下测试一个入站编码器  FixedLengthFrameDecoder;
FixedLengthFrameDecoder
 
 // 用于测试的 Encoder,将读取的 Integer 绝对值化
public class AbsIntegerEncoder extends MessageToMessageEncoder<ByteBuf> {
    @Override
    protected void encode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        while(in.readableBytes() >= 4){
            int i = Math.abs(in.readInt());
            out.add(i);
        }
    }
}
测试代码:
 
    @Test
    public void testAbsIntegerEncoder(){
        EmbeddedChannel channel = new EmbeddedChannel(new AbsIntegerEncoder());
        //测试出站写入
        ByteBuf buf = Unpooled.buffer();
        for(int i = 0; i < 10; i++)
            buf.writeInt(i * -1);
        assertTrue(channel.writeOutbound(buf));
        assertTrue(channel.finish());
        //测试出站读取
        for(int i = 0; i < 10; i++)
            assertEquals((Integer)i,channel.readOutbound());
        assertNull(channel.readOutbound());
    }

异常捕获测试

抛出异常的处理器, FixedLengthFrameDecoder
 
public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
    private final int frameLength;   //帧长度
    private final int maxFrameSize;  //最大帧长度
    public FixedLengthFrameDecoder(int frameLength) {
        this.frameLength = frameLength;
        this.maxFrameSize = 256;
    }
    public FixedLengthFrameDecoder(int frameLength, int maxFrameSize) {
        this.frameLength = frameLength;
        this.maxFrameSize = maxFrameSize;
    }
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        //过长帧异常
        if(in.readableBytes() >= maxFrameSize){
            in.clear();
            throw new TooLongFrameException();
        }
        //帧分割
        while(in.readableBytes() >= frameLength)
            out.add(in.readBytes(frameLength));
    }
}
测试代码:
 
    @Test
    public void testFixedFrameDecoderException(){
        EmbeddedChannel channel = new EmbeddedChannel(new FixedLengthFrameDecoder(4,10));
        ByteBuf buf = Unpooled.buffer();
        for(int i = 0; i < 30; i++)
            buf.writeByte(i);
        try{
            channel.writeInbound(buf.duplicate());
            fail();
        }catch(TooLongFrameException e){
            e.printStackTrace();
        }
    }


猜你喜欢

转载自blog.csdn.net/Al_assad/article/details/79472347