zoukankan      html  css  js  c++  java
  • Netty 系列五(单元测试).

    一、概述和原理

        Netty 的单元测试,主要是对业务逻辑的 ChannelHandler 做测试(毕竟对 Bootstrap、EventLoop 这些做测试着实没有多大意义),模拟一次入站数据或者出站数据,查看数据流经 ChannelHandler 变成什么样了,以此达到测试的目的。

        Netty 的单元测试将Junit4作为测试框架,将 EmbeddedChannel 作为测试通道。基本原理就是:将入站数据或者出站数据写入 EmbeddedChannel 中,然后检查是否有任何东西到达了 ChannelPipeline 的尾端。以这种方式,你便可以知道消息是否流经了 ChannelHandler 以及是否触发了任何 ChannelHandler 的动作,如下图:

        EmbeddedChannel 提供了如下方法进行单元测试:

    writeInbound(Object... msgs): 将入站消息写到 EmbeddedChannel 中。如果可以通过 readInbound()方法从 EmbeddedChannel 中读取数据,则返回 true。
    readInbound() :从 EmbeddedChannel 中读取一个入站消息。任何返回的东西都穿越了整个 ChannelPipeline。如果没有任何可供读取的, 则返回 null。
    writeOutbound(Object... msgs): 将出站消息写到EmbeddedChannel中。如果现在可以通过readOutbound()方法从 EmbeddedChannel 中读取到什么东西,则返回 true。
    readOutbound(): 从 EmbeddedChannel 中读取一个出站消息。任何返回的东西都穿越了整个 ChannelPipeline。如果没有任何可供读取的,则返回 null。
    finish() :将 EmbeddedChannel 标记为完成,并且如果有可被读取的入站数据或者出站数据,则返回 true。这个方法还将会调用 EmbeddedChannel 上的close()方法。

    二、测试入站数据

        1、将我们要测试的 ChannelHandler 写入 EmbeddedChannel 进行测试。

        2、writeInbound(Object... msgs) 将数据写入EmbeddedChannel(模拟接收数据)。

        3、ChannelHandler 处理后如果有返回数据,可以通过readInbound() 验证数据结果。如果没有返回数据,可以在 ChannelHandler 业务逻辑中,打印日志,以达到测试目的。

    public class DecoderTest {
    
    
        //1、利用Junit执行单元测试
        @Test
        public void decoderTest() throws IllegalAccessException {
            ByteBuf buf = Unpooled.buffer();
            for (int i = 0; i < 9; i++) {
                buf.writeByte(i);
            }
            ByteBuf buf1 = buf.duplicate();
            //2、创建EmbeddedChannel,并添加一个Decoder(我们的要测试 ChannelHandler) 其将以3字节帧长度被测试
            EmbeddedChannel embeddedChannel = new EmbeddedChannel(new Decoder(3));
            //3、将数据写入 EmbeddedChannel
            boolean writeInbound = embeddedChannel.writeInbound(buf1.retain());
            assertTrue(writeInbound);
            //4、标记 Channel 为已完成状态
            boolean finish = embeddedChannel.finish();
            assertTrue(finish);
    
            //5、读取数据
            ByteBuf readInbound =  embeddedChannel.readInbound();
            ByteBuf readSlice = buf.readSlice(3);
            assertEquals(readInbound, readSlice);
            readInbound.release();
    
            readInbound =  embeddedChannel.readInbound();
            readSlice = buf.readSlice(3);
            assertEquals(readInbound, readSlice);
            readInbound.release();
    
            readInbound =  embeddedChannel.readInbound();
            readSlice = buf.readSlice(3);
            assertEquals(readInbound, readSlice);
            readInbound.release();
    
            //是否读取完数据了
            assertNull(embeddedChannel.readInbound());
            //释放资源
            buf.release();
    
        }
    }

    三、测试出站数据

        1、将我们要测试的 ChannelHandler 写入 EmbeddedChannel 进行测试。

        2、writeOutbound(Object... msgs) 将数据写入EmbeddedChannel(模拟发送数据)。

        3、ChannelHandler 处理后如果有返回数据,可以通过readOutbound() 验证数据结果。如果没有返回数据,可以在 ChannelHandler 业务逻辑中,打印日志,以达到测试目的。

    public class EncoderTest {
    
        @Test
        public void encoderTest(){
            ByteBuf buf = Unpooled.buffer();
            for (int i =1; i < 10; i++){
                buf.writeInt(i * -1);
            }
            //1、创建一个EmbeddedChannel 并安装要测试的Encoder
            EmbeddedChannel embeddedChannel = new EmbeddedChannel(new Encoder());
            //2、写入数据
            assertTrue(embeddedChannel.writeOutbound(buf));
            assertTrue(embeddedChannel.finish());
            //3、读取数据
            for (int i = 1; i < 10; i++){
                Object o = embeddedChannel.readOutbound();
                System.out.println(o);
            }
            assertNull(embeddedChannel.readOutbound());
        }
    }

    四、结语

        截止到这篇文章,Netty 的基础部分差不多就结束了。不幸的是,公司安排我去研究下 Docker 技术,想在我们项目中使用起来。所以 Netty 的学习就不得不告一段落了~~才翻完《Netty 实战》一半的内容,后面还有编解码器、网络协议、案例研究三个部分,只能先欠下了~

    参考资料:《Netty IN ACTION》

    演示源代码:https://github.com/JMCuixy/NettyDemo/tree/master/src/main/java/org/netty/demo/unit

  • 相关阅读:
    IT程序猿”是怎样练成的? 之 提升内驱力的7大秘籍转
    wp7 退出程序的提示对话框
    生活不容易
    Decorator模式学习
    用序列化方法实现的Prototype的深拷贝
    Observer pettern
    Adapter模式学习
    bridge模式学习
    Composite模式学习
    Prototype原形设计模式
  • 原文地址:https://www.cnblogs.com/jmcui/p/9304508.html
Copyright © 2011-2022 走看看