资讯专栏INFORMATION COLUMN

netty使用EmbeddedChannel对channel的出入站进行单元测试

妤锋シ / 1952人阅读

摘要:一种特殊的实现,它是专门为改进针对的单元测试而提供的。名称职责将入站消息写到中。如果没有任何可供读取的,则返回将标记为完成,如果有可读取的入站或出站数据,则返回。这个方法还将会调用上的方法测试入站消息测试出站消息测试异常处理

一种特殊的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方法
测试入站消息
public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
    private final int frameLength;

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

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {
        while (in.readableBytes() >= frameLength) {
            ByteBuf buf = in.readBytes(frameLength);
            out.add(buf);
        }
    }
}
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.assertTrue(channel.writeInbound(input.retain()));
        Assert.assertTrue(channel.finish());

        ByteBuf read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(3), read);
        read.release();

        read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(3), read);
        read.release();

        read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(3), read);
        read.release();

        Assert.assertNull(channel.readInbound());
        buf.release();
    }

    @Test
    public void testFramesDecoded2() {
        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());
        ByteBuf read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(3), read);
        read.release();

        read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(3), read);
        read.release();

        read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(3), read);
        read.release();

        Assert.assertNull(channel.readInbound());
        buf.release();
    }
}
测试出站消息
public class AbsIntegerEncoder extends MessageToMessageEncoder {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List out) throws Exception {
        while (in.readableBytes() >= 4) {
            int value = Math.abs(in.readInt());
            out.add(value);
        }
    }
}
public class AbsIntegerEncoderTest {
    @Test
    public void testEncoded() {
        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());

        for (int i = 0; i < 10; i++) {
            Assert.assertEquals(Integer.valueOf(i), channel.readOutbound());
        }
        Assert.assertNull(channel.readOutbound());
    }
}
测试异常处理
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 out) throws Exception {
        int readableBytes = in.readableBytes();
        if (readableBytes > maxFrameSize) {
            in.clear();
            throw new TooLongFrameException();
        }
        ByteBuf buf = in.readBytes(readableBytes);
        out.add(buf);
    }
}
public class FrameChunkDecoderTest {
    @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 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());

        ByteBuf read = channel.readInbound();
        Assert.assertEquals(buf.readSlice(2), read);
        read.release();

        read = channel.readInbound();
        Assert.assertEquals(buf.skipBytes(4).readSlice(3), read);
        read.release();
        buf.release();
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75743.html

相关文章

  • Netty学习笔记(二)

    摘要:支持很多协议,并且提供用于数据处理的容器。我们已经知道由特定事件触发。可专用于几乎所有的动作,包括将一个对象转为字节或相反,执行过程中抛出的异常处理。提供了一个容器给链并提供了一个用于管理沿着链入站和出站事件的流动。子类通过进行注册。 前两天写了一点netty相关的知识,并写了一个demo,但是对其原理还是没有深入,今天我们来做一次研究吧 首先让我们来认识一下netty的几个核心人物吧...

    0x584a 评论0 收藏0
  • Netty组件入门学习

    摘要:可以用来接收入站事件和数据,随后使用应用程序的业务逻辑进行处理。因为用户并不是关心所有的事件,因此提供了抽象类和。抽象类最常见的一个情况,你的应用程序会利用一个来接受解码消息,并对该数据应用业务逻辑。 Channel、EventLoop和ChannelFuture Channel——Socket; EventLoop——控制流、多线程处理、并发 ChannelFuture异步通知 ...

    qpal 评论0 收藏0
  • Netty ByteBuf 谁负责谁释放

    摘要:转发自 转发自 http://netty.io/wiki/referenc... Since Netty version 4, the life cycle of certain objects are managed by their reference counts, so that Netty can return them (or their shared resources)...

    Lyux 评论0 收藏0
  • Netty-ChannelHandler-ChannelPipeline

    摘要:只有在详尽的测试之后才应设置为这值使用的默认采样率检测并报告任何发现的泄漏。这是默认级别,适合绝大部分情况使用默认的采样率,报告所发现的任何的泄漏以及对应的消息被访问的位置类似于但是其将会对每次对消息的访问都进行采样。 ChannelHandler Channel生命周期 状态 描述 ChannelUnregistered Channel已经被创建,但未注册到EventLoo...

    warkiz 评论0 收藏0
  • Netty学习-Echo服务器客户端

    摘要:服务器构成至少一个该组件实现了服务器对从客户端接受的数据的处理,即它的业务逻辑引导配置服务器的启动代码。至少,它会将服务器绑定到它要监听连接请求的端口上。需要注意的是,由服务器发送的消息可能会被分块接受。 Netty服务器构成 至少一个ChannelHandler——该组件实现了服务器对从客户端接受的数据的处理,即它的业务逻辑 引导——配置服务器的启动代码。至少,它会将服务器绑定...

    dreamGong 评论0 收藏0

发表评论

0条评论

妤锋シ

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<