測試Netty編解碼器

2018-08-07 15:29 更新

現(xiàn)在我們完成了編碼器和解碼器的學(xué)習(xí),但是總覺得缺少點什么,就是:測試。沒有測試你只看到如果編解碼器工作對一些真正的服務(wù)器運行時,這并不是你應(yīng)該是依靠什么。在第十章中,為一個自定義編寫測試 ChannelHandler通常是通過 EmbeddedChannel。

所以這正是現(xiàn)在做測試我們定制的編解碼器,其中包括一個編碼器和解碼器。讓重新開始編碼器。后面的清單顯示了簡單的編寫單元測試。

Listing 14.5 MemcachedRequestEncoderTest class

public class MemcachedRequestEncoderTest {

@Test
public void testMemcachedRequestEncoder() {
    MemcachedRequest request = new MemcachedRequest(Opcode.SET, "key1", "value1"); //1

    EmbeddedChannel channel = new EmbeddedChannel(new MemcachedRequestEncoder());  //2
    channel.writeOutbound(request); //3

    ByteBuf encoded = (ByteBuf) channel.readOutbound();

    Assert.assertNotNull(encoded);  //4
    Assert.assertEquals(request.magic(), encoded.readUnsignedByte());  //5
    Assert.assertEquals(request.opCode(), encoded.readByte());  //6
    Assert.assertEquals(4, encoded.readShort());//7
    Assert.assertEquals((byte) 0x08, encoded.readByte()); //8
    Assert.assertEquals((byte) 0, encoded.readByte());//9
    Assert.assertEquals(0, encoded.readShort());//10
    Assert.assertEquals(4 + 6 + 8, encoded.readInt());//11
    Assert.assertEquals(request.id(), encoded.readInt());//12
    Assert.assertEquals(request.cas(), encoded.readLong());//13
    Assert.assertEquals(request.flags(), encoded.readInt()); //14
    Assert.assertEquals(request.expires(), encoded.readInt()); //15

    byte[] data = new byte[encoded.readableBytes()]; //16
    encoded.readBytes(data);
    Assert.assertArrayEquals((request.key() + request.body()).getBytes(CharsetUtil.UTF_8), data);
    Assert.assertFalse(encoded.isReadable());  //17

    Assert.assertFalse(channel.finish());
    Assert.assertNull(channel.readInbound());
}

}

  1. 新建 MemcachedRequest 用于編碼為 ByteBuf
  2. 新建 EmbeddedChannel 用于保持 MemcachedRequestEncoder 到測試
  3. 寫請求到 channel 并且判斷是否產(chǎn)生了編碼的消息
  4. 檢查 ByteBuf 是否 null
  5. 判斷 magic 是否正確寫入 ByteBuf
  6. 判斷 opCode (SET) 是否寫入正確
  7. 檢查 key 是否寫入長度正確
  8. 檢查寫入的請求是否額外包含
  9. 檢查數(shù)據(jù)類型是否寫
  10. 檢查是否保留數(shù)據(jù)插入
  11. 檢查 body 的整體大小 計算方式是 key.length + body.length + extras
  12. 檢查是否正確寫入 id
  13. 檢查是否正確寫入 Compare and Swap (CAS)
  14. 檢查是否正確的 flag
  15. 檢查是否正確設(shè)置到期時間的
  16. 檢查 key 和 body 是否正確
  17. 檢查是否可讀

Listing 14.6 MemcachedResponseDecoderTest class

public class MemcachedResponseDecoderTest {

    @Test
    public void testMemcachedResponseDecoder() {
        EmbeddedChannel channel = new EmbeddedChannel(new MemcachedResponseDecoder());  //1

        byte magic = 1;
        byte opCode = Opcode.SET;

        byte[] key = "Key1".getBytes(CharsetUtil.US_ASCII);
        byte[] body = "Value".getBytes(CharsetUtil.US_ASCII);
        int id = (int) System.currentTimeMillis();
        long cas = System.currentTimeMillis();

        ByteBuf buffer = Unpooled.buffer(); //2
        buffer.writeByte(magic);
        buffer.writeByte(opCode);
        buffer.writeShort(key.length);
        buffer.writeByte(0);
        buffer.writeByte(0);
        buffer.writeShort(Status.KEY_EXISTS);
        buffer.writeInt(body.length + key.length);
        buffer.writeInt(id);
        buffer.writeLong(cas);
        buffer.writeBytes(key);
        buffer.writeBytes(body);

        Assert.assertTrue(channel.writeInbound(buffer));  //3

        MemcachedResponse response = (MemcachedResponse) channel.readInbound();
        assertResponse(response, magic, opCode, Status.KEY_EXISTS, 0, 0, id, cas, key, body);//4
    }

    @Test
    public void testMemcachedResponseDecoderFragments() {
        EmbeddedChannel channel = new EmbeddedChannel(new MemcachedResponseDecoder()); //5

        byte magic = 1;
        byte opCode = Opcode.SET;

        byte[] key = "Key1".getBytes(CharsetUtil.US_ASCII);
        byte[] body = "Value".getBytes(CharsetUtil.US_ASCII);
        int id = (int) System.currentTimeMillis();
        long cas = System.currentTimeMillis();

        ByteBuf buffer = Unpooled.buffer(); //6
        buffer.writeByte(magic);
        buffer.writeByte(opCode);
        buffer.writeShort(key.length);
        buffer.writeByte(0);
        buffer.writeByte(0);
        buffer.writeShort(Status.KEY_EXISTS);
        buffer.writeInt(body.length + key.length);
        buffer.writeInt(id);
        buffer.writeLong(cas);
        buffer.writeBytes(key);
        buffer.writeBytes(body);

        ByteBuf fragment1 = buffer.readBytes(8); //7
        ByteBuf fragment2 = buffer.readBytes(24);
        ByteBuf fragment3 = buffer;

        Assert.assertFalse(channel.writeInbound(fragment1));  //8
        Assert.assertFalse(channel.writeInbound(fragment2));  //9
        Assert.assertTrue(channel.writeInbound(fragment3));  //10

        MemcachedResponse response = (MemcachedResponse) channel.readInbound();
        assertResponse(response, magic, opCode, Status.KEY_EXISTS, 0, 0, id, cas, key, body);//11
    }

    private static void assertResponse(MemcachedResponse response, byte magic, byte opCode, short status, int expires, int flags, int id, long cas, byte[] key, byte[] body) {
        Assert.assertEquals(magic, response.magic());
        Assert.assertArrayEquals(key, response.key().getBytes(CharsetUtil.US_ASCII));
        Assert.assertEquals(opCode, response.opCode());
        Assert.assertEquals(status, response.status());
        Assert.assertEquals(cas, response.cas());
        Assert.assertEquals(expires, response.expires());
        Assert.assertEquals(flags, response.flags());
        Assert.assertArrayEquals(body, response.data().getBytes(CharsetUtil.US_ASCII));
        Assert.assertEquals(id, response.id());
    }
}
  1. 新建 EmbeddedChannel ,持有 MemcachedResponseDecoder 到測試
  2. 創(chuàng)建一個新的 Buffer 并寫入數(shù)據(jù),與二進(jìn)制協(xié)議的結(jié)構(gòu)相匹配
  3. 寫緩沖區(qū)到 EmbeddedChannel 和檢查是否一個新的MemcachedResponse 創(chuàng)建由聲明返回值
  4. 判斷 MemcachedResponse 和預(yù)期的值
  5. 創(chuàng)建一個新的 EmbeddedChannel 持有 MemcachedResponseDecoder 到測試
  6. 創(chuàng)建一個新的 Buffer 和寫入數(shù)據(jù)的二進(jìn)制協(xié)議的結(jié)構(gòu)相匹配
  7. 緩沖分割成三個片段
  8. 寫的第一個片段 EmbeddedChannel 并檢查,沒有新的MemcachedResponse 創(chuàng)建,因為并不是所有的數(shù)據(jù)都是準(zhǔn)備好了
  9. 寫第二個片段 EmbeddedChannel 和檢查,沒有新的MemcachedResponse 創(chuàng)建,因為并不是所有的數(shù)據(jù)都是準(zhǔn)備好了
  10. 寫最后一段到 EmbeddedChannel 和檢查新的 MemcachedResponse 是否創(chuàng)建,因為我們終于收到所有數(shù)據(jù)
  11. 判斷 MemcachedResponse 與預(yù)期的值


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號