Сравнивая массивы в утверждениях JUnit, сжатый встроенный способ?


159

Есть ли в JUnit краткий, встроенный способ сделать утверждения равенства для двух массивов одинакового типа? По умолчанию (по крайней мере, в JUnit 4) кажется, что выполняется сравнение экземпляров самого объекта массива.

Например, не работает:

int[] expectedResult = new int[] { 116800,  116800 };
int[] result = new GraphixMask().sortedAreas(rectangles);
assertEquals(expectedResult, result);

Конечно, я могу сделать это вручную с помощью:

assertEquals(expectedResult.length, result.length);
for (int i = 0; i < expectedResult.length; i++)
    assertEquals("mismatch at " + i, expectedResult[i], result[i]);

..но есть ли лучший способ?

Ответы:


298

Используйте org.junit.Assert метод «S assertArrayEquals:

import org.junit.Assert;
...

Assert.assertArrayEquals( expectedResult, result );

Если этот метод недоступен, возможно, вы случайно импортировали класс Assert из junit.framework.


но все, что вы получаете, когда он терпит неудачу для другой длины, это java.lang.AssertionError: array lengths differed, expected.length=6 actual.length=7. Как и большинство сообщений о сбоях JUnit, это не так полезно ... Я советую использовать некоторую платформу утверждений
user1075613

1
@ user1075613 - Я считаю это полезным. Мы утверждали, что массивы были равны, но это не так, и нам дают указание, почему. Оттуда мы можем установить точку останова и детально изучить массивы.
Энди Томас

1
Да, это немного ... полезно. Однако, как вы указываете, в тот момент, когда вы получаете это сообщение, вы спрашиваете себя: «Почему оно не такой длины?» так что вы хотите проверить содержимое. Зачем терять время с отладчиком, когда хорошее сообщение об ошибке может сказать об этом напрямую? (уверен, что иногда вам все еще нужен отладчик, но в большинстве случаев он вам не
нужен

Вы можете отправлять вопросы в систему отслеживания ошибок JUnit . Имейте в виду, однако, что 1) быстрый отказ, в O (1), может быть преимуществом, 2) вывод ошибки подтверждения не должен быть O (n). Система отслеживания проблем JUnit - лучший форум для дальнейшего обсуждения.
Энди Томас

1
@anddero - Assert.assertFalse( Arrays.equals( expectedResult, result )).
Энди Томас

35

Вы можете использовать Arrays.equals(..):

assertTrue(Arrays.equals(expectedResult, result));

14
Что воняет об этом, так это то, что вы НЕТ данных о том, что пошло не так, когда это не удалось.
mBria

8
Приятно, когда вы работаете на более старой версии Junit (как на Android)
Zitrax

2
Если вы хотите увидеть, какие байты не совпадают, вы можете преобразовать их в строку: assertEquals (Arrays.toString (Ожидаемое значение), Arrays.toString (результат));
Эрдем

17

Я предпочитаю конвертировать массивы в строки:

Assert.assertEquals(
                Arrays.toString(values),
                Arrays.toString(new int[] { 7, 8, 9, 3 }));

таким образом я могу ясно видеть, где находятся неправильные значения. Это эффективно работает только для небольших массивов, но я редко использую массивы с количеством элементов больше 7 в своих модульных тестах.

Этот метод работает для примитивных типов и для других типов, когда перегрузка toStringвозвращает всю важную информацию.



4

Используя junit4 и Hamcrest, вы получаете краткий метод сравнения массивов. Это также дает подробную информацию о том, где находится ошибка в трассировке отказа.

import static org.junit.Assert.*
import static org.hamcrest.CoreMatchers.*;

//...

assertThat(result, is(new int[] {56, 100, 2000}));

Выход трассировки сбоя:

java.lang.AssertionError: 
   Expected: is [<56>, <100>, <2000>]
   but: was [<55>, <100>, <2000>]

2

Я знаю, что вопрос касается JUnit4, но если вы застряли в JUnit3, вы можете создать короткую служебную функцию, например:

private void assertArrayEquals(Object[] esperado, Object[] real) {
    assertEquals(Arrays.asList(esperado), Arrays.asList(real));     
}

В JUnit3 это лучше, чем прямое сравнение массивов, поскольку в нем будет подробно указано, какие элементы отличаются.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.