2016-03-18 4 views
1

Согласно многим сообщениям, Assert.assertEquals следует сравнивать коллекции, используя глубокую проницательность, и два массива одного и того же контента должны быть равны.Странное поведение Assert.assertEquals

У меня установлен JUnit 4.12.

Вызов

List<Integer[]> result, targetResult; 
(both are created as ArrayList) 
.... 
Assert.assertEquals("counted small array ", result, targetResult); 

, где результат и targetResult имеют одинаковое содержание, тест не пройден, хотя.

Я посмотрел, как работают assertEquals. Для сравнения массивов Integer он достиг:

//----in AbstractList: 
public boolean equals(Object o) { 
    if (o == this) 
     return true; 
    if (!(o instanceof List)) 
     return false; 

    ListIterator<E> e1 = listIterator(); 
    ListIterator e2 = ((List) o).listIterator(); 
    while (e1.hasNext() && e2.hasNext()) { 
     E o1 = e1.next(); 
     Object o2 = e2.next(); 
     if (!(o1==null ? o2==null : o1.equals(o2))) 
      return false; 
    ... 

//and more deep, in Object: 
public boolean equals(Object obj) { 
    return (this == obj); 
} 

А это означает, что он сравнивает просто ссылки.

Как я могу сделать Assert.assertEquals() правильно работать?

+0

Интересно, где путаница. 'Assert.assertEquals', очевидно, вызывает' # equals' в одном из переданных аргументов, и это будет работать для коллекций, поскольку они переопределяют этот метод, но не будут работать для массивов. И не имеет значения, если вы передаете массивы в Assert.assertEquals' или завернуты в коллекции, так как эти массивы по-прежнему не переопределяют '# equals'. – Tom

+0

@ Тома Ох. Итак, Assert.assertEquals просто НЕ работает в списке . Спасибо, пожалуйста, сделайте ответ из этого комментария - это ответ, который мне нужен ... Я вижу, что он работает так, но так много людей говорили по-другому, что я подумал, может быть, у меня есть дефектный JUnit ... – Gangnus

+0

' Assert.assertEquals' всегда одно и то же: вызывая '# equals', а коллекции также просто вызывают' # equals' из собранных объектов, поэтому вы в конечном итоге используете метод '# equals'' Anything [] 'и никаких массивов не делает переопределить '# equals', поэтому он фактически не сравнивает содержимое массива. Это способ, где «метод обхода», который сравнивает фактическое содержимое массива, например ['Arrays.equals()'] (https: // docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#equals%28boolean[],%20boolean[]%29) – Tom

ответ

4

Проблема с assertEquals заключается в том, что equals(Object) является нормальным. К сожалению, все массивы, присущие объекту, напрямую и не имеют специализированных методов. Это означает, что вам нужно вызвать Arrays.equals (a, b), чтобы сравнить два массива, однако, если эти массивы находятся внутри коллекции, нет никакого способа сделать это удобно.

Примечание: Я не знаю, почему печать [[email protected] является хорошим toString для такого массива либо (это то, что я разглагольствовал против в своем блоге несколько раз)

А это значит, что он сравнивает просто хэш-коды.

Он не сравнивает hashCode(), сравнивает ссылки. hashCode() s не являются адресами памяти, и они не могут быть такими, которые они не могут изменить, когда объект перемещается в памяти.

Если вы хотите, чтобы ваши структуры данных, чтобы быть равными, используйте коллекцию, которая поддерживает равно, как вы ожидаете

List<List<Integer>> result 

если вы вы хотите эффективность в качестве int использует 4 байта и Integer может использовать 20 байт, включая это ссылка.

List<int[]> result 

public static void assertEqualsArray(List<Int[]> a, List<int[]> b) { 
    // compare the list of arrays. 
} 
+0

1. Спасибо, я уже написал свой метод, который выполняет эту работу. Но я хотел понять, в чем проблема с Assert.assertEquals(). 2. Я помню, что List [int] невозможно. Это что-то новое, не так ли? 3. Конечно, ссылки. Я немного утонул в хэш-кодах. Исправленный. – Gangnus

+0

@Gangnus 1. assertEquals предполагает, что метод .equals (Object) является нормальным. 2. Список может быть возможен на Java 10. 3. Сбивание хэш-кода с адресами памяти является обычным явлением, даже если вы читаете Javadoc для этого метода. O_O –

+0

Я имел в виду список , извините. Я думал, это тоже запрещено. – Gangnus

0

Рассмотрим:

Assert.assertArrayEquals(result.toArray(), targetResult.toArray()); 
Смежные вопросы