第 11 章 用测试模拟真实网络
11.1 为什么不能只手工运行一次
手工看到“收到:你好”只能证明某次输入成功。它没有证明分片、合并、超长输入和关闭时机都正确。网络相关程序尤其需要构造边界条件。
Netty 的 EmbeddedChannel 允许在内存中运行 Pipeline,不需要占用真实端口。向 writeInbound 喂字节,检查 readOutbound 得到的响应,就能测试编解码器和业务处理器的组合。
11.2 最关键的测试过程
ch.writeInbound(Unpooled.copiedBuffer("he", CharsetUtil.UTF_8));
assertNull(ch.readOutbound());
ch.writeInbound(Unpooled.copiedBuffer("llo\nworld\n", CharsetUtil.UTF_8));第一步不应产生回复,因为还没遇到换行。第二步应产生两条响应,分别对应 hello 和 world。这样一次同时覆盖了消息分片与消息合并。
注意:writeInbound 返回值表示是否有消息留在入站队列供读取,不是“网络读取是否成功”。本例业务处理器消费了入站消息并生成出站消息,所以判断业务结果应读取出站队列。
11.3 随书测试覆盖什么
工程包含五项测试:普通文本的分片与合并;UTF-8 字符内部的分片;quit 的响应与关闭;超长行的拒绝;长度字段帧的分片重组。测试源码见附录 A。
这组测试支持教学示例的主要行为,但没有验证大规模并发、TLS、网络抖动下的长期运行或生产吞吐能力。测试结论必须限定在实际覆盖的范围内。
11.4 下一步可以增加什么
你可以增加:空行、CRLF、刚好等于长度上限、断线时残缺帧、连续多条消息、错误 UTF-8、连接失败。若业务要求严格拒绝非法 UTF-8,需要显式设计严格解码策略;普通字符串转换不应被当作输入合法性校验。
真实端到端测试则要启动服务器,建立 Socket 连接,发送字节并验证响应。它验证启动配置与网络路径,而 EmbeddedChannel 更适合精确测试 Pipeline 的边界行为。两者相互补充。
小练习: 为什么“整条中文一次输入能通过”还不足以证明中文处理正确?