Недавно я работал с Netty и создал конвейер кодеров / декодеров, как описано в этом превосходном руководстве, и хотел проверить, работают ли кодеры и декодеры без необходимости отправлять реальные сообщения.
К счастью, есть встроенный канал, который действительно облегчает нашу жизнь.
Допустим, у нас есть сообщение «Foo», которое мы хотим отправить по сети. Он содержит только одно целочисленное значение, поэтому мы просто отправим его и восстановим ‘Foo’ с другой стороны.
Мы могли бы написать следующий кодер для этого:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// Examples uses Netty 4.0.28.Finalpublic static class MessageEncoder extends MessageToMessageEncoder<Foo>{ @Override protected void encode( ChannelHandlerContext ctx, Foo msg, List<Object> out ) throws Exception { ByteBuf buf = ctx.alloc().buffer(); buf.writeInt( msg.value() ); out.add( buf ); }} public static class Foo{ private Integer value; public Foo(Integer value) { this.value = value; } public int value() { return value; }} |
Таким образом, все, что мы делаем, это извлекаем поле ‘value’ из ‘Foo’ и помещаем его в список, который передается вниз по течению.
Давайте напишем тест, который имитирует отправку сообщения «Foo» и имеет пустую попытку декодера обработать сообщение:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Testpublic void shouldEncodeAndDecodeVoteRequest(){ // given EmbeddedChannel channel = new EmbeddedChannel( new MessageEncoder(), new MessageDecoder() ); // when Foo foo = new Foo( 42 ); channel.writeOutbound( foo ); channel.writeInbound( channel.readOutbound() ); // then Foo returnedFoo = (Foo) channel.readInbound(); assertNotNull(returnedFoo); assertEquals( foo.value(), returnedFoo.value() );} public static class MessageDecoder extends MessageToMessageDecoder<ByteBuf>{ @Override protected void decode( ChannelHandlerContext ctx, ByteBuf msg, List<Object> out ) throws Exception { }} |
Итак, в тесте мы пишем ‘Foo’ в исходящий канал, а затем читаем его обратно во входящий канал и затем проверяем, что у нас есть. Если мы запустим этот тест сейчас, вот что мы увидим:
|
1
2
|
junit.framework.AssertionFailedError at NettyTest.shouldEncodeAndDecodeVoteRequest(NettyTest.java:28) |
Возвращаемое нами сообщение является нулевым, что имеет смысл, учитывая, что мы не удосужились написать декодер Давайте реализуем декодер тогда:
|
1
2
3
4
5
6
7
8
9
|
public static class MessageDecoder extends MessageToMessageDecoder<ByteBuf>{ @Override protected void decode( ChannelHandlerContext ctx, ByteBuf msg, List<Object> out ) throws Exception { int value = msg.readInt(); out.add( new Foo(value) ); }} |
Теперь, если мы снова запустим наш тест, все будет зеленым и счастливым. Теперь мы можем пойти и кодировать / декодировать некоторые более сложные структуры и соответственно обновить наш тест.
| Ссылка: | Netty: тестирование кодировщиков / декодеров от нашего партнера JCG Марка Нидхэма в блоге Марка Нидхэма . |