单元测试-Netty笔记(九)

EmbeddedChannel 概述

Netty 提供了它所谓的 Embedded 传输,用于测试 ChannelHandler 。这个传输是一种特殊的 Channel 实现 EmbeddedChannel 的功能,这个实现提供了通过 ChannelPipeline 传播事件的简便方法。

将入站数据或者出站数据写入到 EmbeddedChannel 中,然后检查是否有任何东西到达了 ChannelPipeline 的尾端。以这种方式,你便可以确定消息是否已经被编码或解码过了,以及是否触发了任何的 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() 方法

入站数据由 ChannelInboundHandler 处理,代表从远程节点读取的数据。出站数据由 ChannelOutboundHandler 处理,代表将要写到远程节点的数据。根据你要测试的 ChannelHandler ,你将使用 *Inbound()*Outbound() 方法对。

你可以使用 writeOutbound() 方法将消息写到 Channel 中,并通过 ChannelPipeline 沿着出站的方向传递。随后,你可以使用 readOutbound() 方法来读取已被处理过的消息,以确定结果是否和预期一样。类似地,对于入站数据,你需要使用 writeInbound()readInbound() 方法。

EmbeddedChannel 的数据流:

单元测试-Netty笔记(九)

使用 EmbeddedChannel 测试 ChannelHandler

测试入站消息

下图展示了一个简单的 ByteToMessageDecoder 实现。给定足够的数据,这个实现将产生固定大小的帧。如果没有足够的数据可供读取,它将等待下一个数据块的到来,并将再次检查是否能够产生一个新的帧。

单元测试-Netty笔记(九)

FixedLengthFrameDecoder :

测试 FixedLengthFrameDecoder :

测试出站消息

使用 EmbeddedChannel 测试一个编码器形式的 ChannelOutboundHandler ,编码器是一种将一种消息转换为另一种的组件。AbsIntegerEncoder 是 Netty 的 MessageToMessageEncoder 的一个特殊化的实现,用于将负值整数转换为绝对值。

下面的示例将会按照下列方式工作:

  • 持有 AbsIntegerEncoder 的 EmbeddedChannel 将会以 4 字节的负整数的形式写出站数据。
  • 编码器将从传入的 ByteBuf 中读取每个负整数,并将会调用 Math.abs() 方法来获取其绝对值。
  • 编码器将会把每个负整数的绝对值写到 ChannelPipeline 中。
单元测试-Netty笔记(九)

AbsIntegerEncoder :

测试 AbsIntegerEncoder :

测试异常处理

应用程序通常需要执行比转换数据更加复杂的任务。例如,你可能需要处理格式不正确的输入或者过量的数据。下面示例中,如果所读取的字节数超出了某个特定的限制,我们将会抛出一个 TooLongFrameException 异常。这是一种经常用来防范资源被耗尽的方法。

下图中,最大的帧数大小已经被设置为 3 字节。如果一个帧的大小超出了该限制,那么程序将会丢弃它的字节,并抛出一个 TooLongFrameException 。位于 ChannelPipeline 中的其他 ChannelHandler 可以选择在 exceptionCaaught() 方法中处理该异常或者忽略它。

单元测试-Netty笔记(九)

FrameChunkDecoder :

测试 FrameChunkDecoder :

    A+
发布日期:2019年04月20日  所属分类:Java
标签:
六阿哥

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: