使用带有通配符的assertArrayEquals()?

时间:2011-10-25 07:06:14

标签: java junit bytearray mockito hamcrest

我想测试生成用于发送为UDP数据包的字节数组的代码。

虽然我无法重现测试中的每个字节(例如随机字节,时间戳),但我想测试我可以预先确定的字节。

使用JUnit 4.8(和Mockito 1.8)可能会出现以下情况吗?

Packet packet = new RandomPacket();

byte[] bytes = new byte[] {
    0x00, 0x02, 0x05, 0x00, anyByte(), anyByte(), anyByte(), anyByte(), 0x00
};

assertArrayEquals(packet.getBytes(), bytes);

上面的示例当然不起作用,我只是在assertArrayEquals()中搜索使用某种通配符的方法。

PS:我现在唯一的选择是单独检查每个字节(并省略随机字节)。但这很安静乏味而且不可重复使用。


感谢JB Nizet的回答我现在有以下代码,工作得很好:

private static int any() {
    return -1;
}

private static void assertArrayEquals(int[] expected, byte[] actual) {
    if(actual.length != expected.length) {
        fail(String.format("Arrays differ in size: expected <%d> but was <%d>", expected.length, actual.length));
    }

    for(int i = 0; i < expected.length; i ++) {
        if(expected[i] == -1) {
            continue;
        }

        if((byte) expected[i] != actual[i]) {
            fail(String.format("Arrays differ at element %d: expected <%d> but was <%d>", i, expected[i], actual[i]));
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您可以简单地将您期望的数组编写为整数数组,并使用特殊值(例如-1)来表示通配符。这与输入流的读取方法相同。您只需编写自定义assertEqualsWithWildCard(int[] expected, byte[] actual)

答案 1 :(得分:1)

如果您要编写大量这样的代码,我会编写一个单独的类来将数据包“解码”为有意义的字段。然后(当然,在测试类本身有效之后),您可以编写合理的测试,如

assertEquals(42, packet.length());
assertEquals(0xDEADBEEF, packet.checksum());

这样,你不是“省略随机字节”,你的代码将更具可读性(如果有点冗长)。