一種特殊的Channel 實現——EmbeddedChannel,它是Netty 專門為改進針對ChannelHandler 的單元測試而提供的。
將入站數據或者出站數據寫入到EmbeddedChannel 中,然后檢查是否有任何東西到達了ChannelPipeline 的尾端。以這種方式,你便可以確定消息是否已經被編碼或者被解碼過了,以及是否觸發了任何的ChannelHandler 動作。
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 處理,代表將要寫到遠程節點的數據。
使用writeOutbound()方法將消息寫到Channel 中,並通過ChannelPipeline 沿着出站的方向傳遞。隨后,你可以使用readOutbound()方法來讀取已被處理過的消息,以確定結果是否和預期一樣。 類似地,對於入站數據,你需要使用writeInbound()和readInbound()方法。
在每種情況下,消息都將會傳遞過ChannelPipeline,並且被相關的ChannelInboundHandler 或者ChannelOutboundHandler 處理。

測試入站消息
我們有一個簡單的ByteToMessageDecoder 實現。給定足夠的數據,這個實現將產生固定大小的幀。如果沒有足夠的數據可供讀取,它將等待下一個數據塊的到來,並將再次檢查是否能夠產生一個新的幀。
這個特定的解碼器將產生固定為3 字節大小的幀。因此,它可能會需要多個事件來提供足夠的字節數以產生一個幀。

測試出站消息
在測試的處理器—AbsIntegerEncoder,它是Netty 的MessageToMessageEncoder 的一個特殊化的實現,用於將負值整數轉換為絕對值。
該示例將會按照下列方式工作:
持有AbsIntegerEncoder 的EmbeddedChannel 將會以4 字節的負整數的形式寫出站數據;
編碼器將從傳入的ByteBuf 中讀取每個負整數,並將會調用Math.abs()方法來獲取其絕對值;
編碼器將會把每個負整數的絕對值寫到ChannelPipeline 中。

測試異常處理
應用程序通常需要執行比轉換數據更加復雜的任務。例如,你可能需要處理格式不正確的輸入或者過量的數據。在下一個示例中,如果所讀取的字節數超出了某個特定的限制,我們將會拋出一個TooLongFrameException。
這是一種經常用來防范資源被耗盡的方法。設定最大的幀大小已經被設置為3 字節。如果一個幀的大小超出了該限制,那么程序將會丟棄它的字節,並拋出一個TooLongFrameException。位於ChannelPipeline 中的其他ChannelHandler 可以選擇在exceptionCaught()方法中處理該異常或者忽略它。

