#java #junit #bytearray #mockito #hamcrest
#java #юнит #bytearray #mockito #хэмкрест
Вопрос:
Я хочу протестировать код, который создает байтовые массивы, используемые для отправки в виде 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]));
}
}
}
Ответ №1:
Вы могли бы просто записать ожидаемый массив в виде массива целых чисел и использовать специальное значение (например, -1) для представления подстановочного знака. Это тот же трюк, что и методы чтения входных потоков. Вам просто нужно будет написать свой заказ assertEqualsWithWildCard(int[] expected, byte[] actual)
.
Комментарии:
1. Простое, но понятное решение. Почему я не подумал об этом? Я добавил код к своему вопросу.
2. Может быть, использование a
Byte[]
было бы более уместным? Тогда подстановочные знаки будутnull
. Это был бы один из немногих случаев, когда aByte[]
был действительно полезен 😉3. @Joachim: преимущество использования целых чисел также заключается в возможности легко записывать байтовые литералы: 0xBC против (байта) 0xBC
4. @JB: Я вижу, в этом случае код в ответе неверен «, хотя. Потому что
byte
в строке отсутствует приведение кif(expected[i] != actual[i])
: Так и должно бытьif ((byte) expected[i] != actual[i])
.5. Да, действительно. И порядок аргументов должен быть обратным, потому что соглашение JUnit должно иметь ожидаемое значение в качестве первого аргумента, а фактическое — в качестве второго.
Ответ №2:
Если вы собираетесь писать много подобного кода, я бы написал отдельный класс для «декодирования» пакета в значимые поля. Затем (конечно, после проверки того, что сам класс работает) вы можете написать разумные тесты, такие как
assertEquals(42, packet.length());
assertEquals(0xDEADBEEF, packet.checksum());
и т.д.
Таким образом, вы не «пропускаете случайные байты», и ваш код будет намного более читабельным (если немного более подробным).
Комментарии:
1. Это звучит хорошо, но кажется немного чересчур, поскольку пакетов для тестирования не так уж много.