一种特殊的Channel实现----EmbeddedChannel,它是Netty专门为改进针对ChannelHandler的单元测试而提供的。

名称 职责
writeInbound 将入站消息写到EmbeddedChannel中。如果可以通过readInbound方法从EmbeddedChannel中读取数据,则返回true
readInbound 从EmbeddedChannel中读取入站消息。任何返回东西都经过整个ChannelPipeline。如果没有任何可供读取的,则返回null
writeOutbound 将出站消息写到EmbeddedChannel中,如果现在可以通过readOutbound从EmbeddedChannel中读取到东西,则返回true
readOutbound 从EmbeddedChannel中读取出站消息。任何返回东西都经过整个ChannelPipeline。如果没有任何可供读取的,则返回null
finish 将EmbeddedChannel标记为完成,如果有可读取的入站或出站数据,则返回true。这个方法还将会调用EmbeddedChannel上的close方法

测试入站消息

  1. public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
  2. private final int frameLength;
  3. public FixedLengthFrameDecoder(int frameLength) {
  4. if (frameLength <= 0) {
  5. throw new IllegalArgumentException("frameLength must be positive integer: " + frameLength);
  6. }
  7. this.frameLength = frameLength;
  8. }
  9. @Override
  10. protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
  11. while (in.readableBytes() >= frameLength) {
  12. ByteBuf buf = in.readBytes(frameLength);
  13. out.add(buf);
  14. }
  15. }
  16. }
  1. public class FixedLengthFrameDecoderTest {
  2. @Test
  3. public void testFramesDecoded() {
  4. ByteBuf buf = Unpooled.buffer();
  5. for (int i = 0; i < 9; i++) {
  6. buf.writeByte(i);
  7. }
  8. ByteBuf input = buf.duplicate();
  9. EmbeddedChannel channel = new EmbeddedChannel(new FixedLengthFrameDecoder(3));
  10. Assert.assertTrue(channel.writeInbound(input.retain()));
  11. Assert.assertTrue(channel.finish());
  12. ByteBuf read = channel.readInbound();
  13. Assert.assertEquals(buf.readSlice(3), read);
  14. read.release();
  15. read = channel.readInbound();
  16. Assert.assertEquals(buf.readSlice(3), read);
  17. read.release();
  18. read = channel.readInbound();
  19. Assert.assertEquals(buf.readSlice(3), read);
  20. read.release();
  21. Assert.assertNull(channel.readInbound());
  22. buf.release();
  23. }
  24. @Test
  25. public void testFramesDecoded2() {
  26. ByteBuf buf = Unpooled.buffer();
  27. for (int i = 0; i < 9; i++) {
  28. buf.writeByte(i);
  29. }
  30. ByteBuf input = buf.duplicate();
  31. EmbeddedChannel channel = new EmbeddedChannel(new FixedLengthFrameDecoder(3));
  32. Assert.assertFalse(channel.writeInbound(input.readBytes(2)));
  33. Assert.assertTrue(channel.writeInbound(input.readBytes(7)));
  34. Assert.assertTrue(channel.finish());
  35. ByteBuf read = channel.readInbound();
  36. Assert.assertEquals(buf.readSlice(3), read);
  37. read.release();
  38. read = channel.readInbound();
  39. Assert.assertEquals(buf.readSlice(3), read);
  40. read.release();
  41. read = channel.readInbound();
  42. Assert.assertEquals(buf.readSlice(3), read);
  43. read.release();
  44. Assert.assertNull(channel.readInbound());
  45. buf.release();
  46. }
  47. }

测试出站消息

  1. public class AbsIntegerEncoder extends MessageToMessageEncoder<ByteBuf> {
  2. @Override
  3. protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
  4. while (in.readableBytes() >= 4) {
  5. int value = Math.abs(in.readInt());
  6. out.add(value);
  7. }
  8. }
  9. }
  1. public class AbsIntegerEncoderTest {
  2. @Test
  3. public void testEncoded() {
  4. ByteBuf buf = Unpooled.buffer();
  5. for (int i = 0; i < 10; i++) {
  6. buf.writeInt(i * -1);
  7. }
  8. EmbeddedChannel channel = new EmbeddedChannel(new AbsIntegerEncoder());
  9. Assert.assertTrue(channel.writeOutbound(buf));
  10. Assert.assertTrue(channel.finish());
  11. for (int i = 0; i < 10; i++) {
  12. Assert.assertEquals(Integer.valueOf(i), channel.readOutbound());
  13. }
  14. Assert.assertNull(channel.readOutbound());
  15. }
  16. }

测试异常处理

  1. public class FrameChunkDecoder extends ByteToMessageDecoder {
  2. private final int maxFrameSize;
  3. public FrameChunkDecoder(int maxFrameSize) {
  4. this.maxFrameSize = maxFrameSize;
  5. }
  6. @Override
  7. protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
  8. int readableBytes = in.readableBytes();
  9. if (readableBytes > maxFrameSize) {
  10. in.clear();
  11. throw new TooLongFrameException();
  12. }
  13. ByteBuf buf = in.readBytes(readableBytes);
  14. out.add(buf);
  15. }
  16. }
  1. public class FrameChunkDecoderTest {
  2. @Test
  3. public void testFramesDecoded() {
  4. ByteBuf buf = Unpooled.buffer();
  5. for (int i = 0; i < 9; i++) {
  6. buf.writeByte(i);
  7. }
  8. ByteBuf input = buf.duplicate();
  9. EmbeddedChannel channel = new EmbeddedChannel(new FrameChunkDecoder(3));
  10. Assert.assertTrue(channel.writeInbound(input.readBytes(2)));
  11. try {
  12. channel.writeInbound(input.readBytes(4));
  13. Assert.fail();
  14. } catch (TooLongFrameException e) {
  15. }
  16. Assert.assertTrue(channel.writeInbound(input.readBytes(3)));
  17. Assert.assertTrue(channel.finish());
  18. ByteBuf read = channel.readInbound();
  19. Assert.assertEquals(buf.readSlice(2), read);
  20. read.release();
  21. read = channel.readInbound();
  22. Assert.assertEquals(buf.skipBytes(4).readSlice(3), read);
  23. read.release();
  24. buf.release();
  25. }
  26. }

netty使用EmbeddedChannel对channel的出入站进行单元测试的更多相关文章

  1. 自顶向下深入分析Netty(六)--Channel总述

    自顶向下深入分析Netty(六)--Channel总述 自顶向下深入分析Netty(六)--Channel源码实现 6.1 总述 6.1.1 Channel JDK中的Channel是通讯的载体,而N ...

  2. Netty那点事: 概述, Netty中的buffer, Channel与Pipeline

    Netty那点事(一)概述 Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户ne ...

  3. netty做集群 channel共享 方案

    netty做集群 channel如何共享? 方案一: netty 集群,通过rocketmq等MQ 推送到所有netty服务端, channel 共享无非是要那个通道都可以发送消息向客户端, MQ广播 ...

  4. Netty源码分析之ChannelPipeline—入站事件的传播

    之前的文章中我们说过ChannelPipeline作为Netty中的数据管道,负责传递Channel中消息的事件传播,事件的传播分为入站和出站两个方向,分别通知ChannelInboundHandle ...

  5. Netty源码分析之ChannelPipeline—出站事件的传播

    上篇文章中我们梳理了ChannelPipeline中入站事件的传播,这篇文章中我们看下出站事件的传播,也就是ChannelOutboundHandler接口的实现. 1.出站事件的传播示例 我们对上篇 ...

  6. Netty源码分析--Channel注册(上)(五)

    其实在将这一节之前,我们来分析一个东西,方便下面的工作好开展. 打开启动类,最开始的时候创建了一个NioEventLoopGroup 事件循环组,我们来跟一下这个. 这里bossGroup, 我传入了 ...

  7. Netty源码分析--Channel注册(中)(六)

    接上一篇,我们继续看 不知道大家第一次看这段代码的时候有没有一脸懵逼,反正我是一脸懵,为什么这个if else 最终都是调用的register0方法,都是一样的. 其实这里就是为什么Netty是线程安 ...

  8. 003——Netty之Buffer、Channel以及多路复用器Selector

    Buffer 1.缓冲区类型 2.缓冲区定义 (1)Buffer是一个对象,其中包含写入与读出的数据.是新IO与原IO的重要区别.任何情况下访问NIO中的数据都需要通过缓存区进行操作. (2)Buff ...

  9. netty(五) channel

    问题 channel 是如何处理发送一半中断后继续重发的 channel 具体作用是什么 概述 这一节我们将介绍 Channel 和内部接口 Unsafe .其中Unsafe 是内部接口,聚合在Cha ...

随机推荐

  1. Appcan 日期控件

    某个页面的onclick事件 <div id="topSendDate" class="ub ub-f1" onclick="appcan.wi ...

  2. ASP.NET Core on K8S学习初探(3)部署API到K8S

    在上一篇<基本概念快速一览>中,我们把基本的一些概念快速地简单地不求甚解地过了一下,本篇开始我们会将ASP.NET Core WebAPI部署到K8S,从而结束初探的旅程. Section ...

  3. 使用pymysql操作mysql数据库

    PyMySQL的安装和连接 PyMySQL的安装 python3. -m pip install pymysql python连接数据库 import pymysql # 创建连接 conn = py ...

  4. 用python的matplotlib和numpy库绘制股票K线均线的整合效果(含从网络接口爬取数据和验证交易策略代码)

    本人最近在尝试着发表“以股票案例入门Python编程语言”系列的文章,在这些文章里,将用Python工具绘制各种股票指标,在讲述各股票指标的含义以及计算方式的同时,验证基于各种指标的交易策略,本文是第 ...

  5. Codeforces Gym101246H:``North-East''(LIS+思维)

    http://codeforces.com/gym/101246/problem/H 题意:在二维平面上有n个点,从最左下角的点出发,每次走只能走在当前的点的右上角的点(xj > xi, yj ...

  6. Codeforces 776D:The Door Problem(DFS染色)

    http://codeforces.com/problemset/problem/776/D 题意:有n个门,m个开关,每个门有一个当前的状态(0表示关闭,1表示打开),每个开关控制k个门,但是每个门 ...

  7. Oracle 数据库连接不上 登录一直卡死

    在此记录下半个月来,oracle数据库本地神奇地连接不了的事件. 描述下我的情况: (1)使用navicat连接本地的数据库,结果一直卡[正在连接中(无响应)]: (2)使用PL/SQL连接本地的数据 ...

  8. vue中v-model的数据双向绑定(重要)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 嵊州D3T3 light

    嵊州D3T3 light 光恰似水 兄弟俩曾经 k 次受到过父母的物质激励. 一开始,兄弟俩的能力值为 1,最后,兄弟俩的能力值是 1 + (2 ^k−1)/ n . 当兄弟俩受到价值为 mi 的物质 ...

  10. 堡垒机-jumpserver

    目录 官方网站 Jumpserver 软件包环境要求: 环境 手动本地jumpserver-服务端搭建 初始化一些系统环境设置: 安装相关软件 安装 组件 自建服务器极速安装步骤 0. 防火墙.Sel ...