我使用testng作为我的测试框架,mockito for mocks。
我所拥有的是:我正在尝试为将要测试的一个类(数据包处理器)编写测试。分组处理器有两种称为发送和接收的方法,其中接收方法从源输入流接收一个特定网络协议的数据包,然后解析它的报头,返回实际的数据包内容。 send方法获取有效负载,创建数据包,并通过网络发送。
问题是这些数据包是可选的压缩,加密并为它们计算mac。我的问题一般是,加密,mac计算和压缩是由从一些抽象类派生的单独对象完成的,所以我需要模拟它们。但是,如何使解密器的模拟工作正常,以便返回可以验证的有意义的数据?
在调用decrypt方法时,我似乎无法创建一个虚拟数据包并返回一个好数据包。这是因为数据包是可变长度的,并且长度本身是加密的,因此被测对象需要做的是,读取第一个密文块,解密,从结果字节数组中读取长度,然后读取其余的密文。数据包,解密和合并以创建完整数据包。然后,如果足够长,每个数据包将有两个解密调用,我可能不仅需要生成一个虚假的可验证数据包,还要以某种方式拆分它,并做一些奇特的事情。我不太清楚如何处理这种情况。
我目前有针对没有加密,完整性保护和压缩的情况下的书面测试和数据包发送方/接收方。
这是接收方法的代码:
public byte[] receive(final DataInput in) throws SshProtocolException, SshIoException {
assert in != null;
try {
int length = 0, paddingLength = 0;
/* Read packet length, ignoring timeouts and returning null on eof. */
while (true) {
try {
length = in.readInt();
break;
} catch (SocketTimeoutException e) {} catch (EOFException e) {
return null;
}
}
logger.debug("receiving next packet of length {}", length);
/*
* Minimum packet length is 16 bytes, the length field does not count itself, so
* 12 bytes + length field size.
*/
if (Integer.compareUnsigned(length, 12) < 0) {
logger.error("malformed packet: packet is too small, must be at least 16 bytes");
throw new SshProtocolException("malformet packet: packet is too small, must be at least 16 bytes");
}
/* Max packet size is 35000 bytes with length field. */
if (Integer.compareUnsigned(length, 34996) > 0) {
logger.error("malformed packet: packet too large");
throw new SshProtocolException("malformed packet: packet too large");
}
/* Must be a multiple of cipher block size or 8, whichever is larger. */
if (Integer.remainderUnsigned(length + 4, 8) != 0) {
logger.error("malformed packet: packet must be aligned to the cipher block size");
throw new SshProtocolException("malformed packet: packet must be aligned to the cipher block size");
}
/* Read packet. */
byte[] packet = new byte[length];
in.readFully(packet);
paddingLength = packet[0] & 0xFF;
if (paddingLength < 4) {
logger.error("malformed packet: padding length must be at least 4 bytes");
throw new SshProtocolException("malformed packet: padding length must be at least 4 bytes");
}
int payloadLength = length - paddingLength - 1;
if (Integer.compareUnsigned(payloadLength, 32768) > 0) {
logger.error("malformed packet: payload too large");
throw new SshProtocolException("malformed packet: payload too large");
}
byte[] payload = new byte[payloadLength];
System.arraycopy(packet, 1, payload, 0, payloadLength);
logger.debug("padding length: {}, payload length: {}", paddingLength, payloadLength);
return payload;
} catch (EOFException e) {
throw new SshProtocolException("malformed packet received, end of stream before the end of packet");
} catch (IOException e) {
throw new SshIoException("i/o error while receiving the ssh packet: " + e.getMessage(), e);
}
}
这是测试成功的示例测试:
@Test
public void receivingPacketReturnsPayloadWhenPacketValid() throws SshException, IOException {
byte[] packet = generatePacket(12, 7, "test".getBytes(), 7);
DataInputStream in = new DataInputStream(new ByteArrayInputStream(packet));
SshPacketProcessor proc = new SshPacketProcessor(random, inputHolder, outputHolder);
byte[] payload = proc.receive(in);
assertEquals(new String(payload), "test");
}
generatePacket()方法使用提供的数据生成测试数据包,并允许在需要时生成无效数据包。