EmbededChannel 单元测试

概述

    前面的章节已经对 Netty 的各个组件进行了学习即使用。了解到 Netty 在使用的过程中,基本上所有的程序逻辑部分的主体都是在 ChannelHandler 中完成的,所以对 ChannelHandler 进行认真仔细的测试是很重要的一个环节了。那么,如何很好的测试 ChannelHandler 了?答案就是 EmbededChannel 。

EmbededChannel

    EmbededChannel 其实就是 Netty 提供的一种特殊的 Channel,主要功能就是验证 ChannelPipeLine 中 ChannelHandler 编写的逻辑是否正常。它的实现原理,简单说来就是:把入站或者出站数据写入到 EmbededChannel 中,然后通过 EmbededChannel 提供的方法验证这些数据是否正常的通过所有的 ChannelHandler。如果通过了,则正确;否则就是错误的。它提供了如下方法

名称z作用
writeInbound(Object...msgs)将入站数据写到 EmbededChannel 中。然后通过 readInbound()方法从 EmbededChannel 中读取数据,则返回 true
readInbound()从 EmbededChannel 中 读取一个入站的消息。任何返回的结果都是穿越了整个 ChannelPipeLine 的。如果没有任何可供读取的,则返回 null
writeOutbound(Object...msgs)将出站数据写到 EmbededChannel 中。然后通过 readOutbound()方法从 EmbededChannel 中读取数据,则返回 true
readOutbound()从 EmbededChannel 中 读取一个出站的消息。任何返回的结果都是穿越了整个 ChannelPipeLine 的。如果没有任何可供读取的,则返回 null
finish()j将 EmbededChannel 标记为完成,并且如果有可被读取的入站数据或者出站数据,则返回 true。这个方法还将会调用 EmbededChannel 上的 close()方法

    如下图展示了 EmbededChannel 验证 ChannelHandler 的原理


EmbededChannel 的使用示例

    编写一个 FrameChunkDecoder 的 ChannelHandler,该 handler 的作用是限制每一帧数据的大小不超过 4 个字节,如果超过了则会抛出异常。

    FrameChunkDecoder 类

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.TooLongFrameException;
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){
			//discard the bytes
			in.clear();
			throw new TooLongFrameException();
		}
		ByteBuf buf = in.readBytes(readableBytes);
		out.add(buf);
	}

}
     FrameChunkDecoderTest 类
import static org.junit.Assert.*;

import org.junit.Assert;
import org.junit.Test;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.TooLongFrameException;
public class FrameChunkDecoderTest{
	
	@Test
	public void testFrameDecoded(){
		ByteBuf buf = Unpooled.buffer();
		for (int i = 0; i < 9; i++) {
			buf.writeByte(i);
		}
		ByteBuf input = buf.duplicate();
		EmbeddedChannel channel = new EmbeddedChannel(new FrameChunkDecoder(3));
		//向 EmbededChannel 中写入 2 字节,并且断言他们将会产生一个新帧
		assertTrue(channel.writeInbound(input.readBytes(2)));
		try{
			//写入一个 4 帧大小的数据,并且捕获抛出来的异常
			channel.writeInbound(input.readBytes(4));
			Assert.fail();
		}catch(TooLongFrameException e){
			System.out.println("Frame too long");
		}
		assertTrue(channel.writeInbound(input.readBytes(3)));
		//将channel 标记为已完成的状态
		assertTrue(channel.finish());
		
		
		//***读取帧*//
		ByteBuf read = channel.readInbound();
		//确定第一帧是否是2个字节
		assertEquals(buf.readSlice(2), read);
		read.release();
		
		read = channel.readInbound();
		//跳过 4 个字节,直接读取最后 3 个字节
		assertEquals(buf.skipBytes(4).readSlice(3), read);
		read.release();
		buf.release();
	}

}

总结

    采用 Junit 测试工具来进行单元测试是一种非常有效的方式。本章节通过 Junit 和 EmbededChannel 来实现了对ChannelHandler 测试,可以感受到测试是如此的有效和简单。下一章节将对 Netty 的编解码器进行学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值