Porównywanie tablic w asercjach JUnit, zwięzły wbudowany sposób?

159

Czy istnieje zwięzły, wbudowany sposób wykonywania asercji równości na dwóch tablicach o podobnym typie w JUnit? Domyślnie (przynajmniej w JUnit 4) wydaje się, że wykonuje porównanie instancji na samym obiekcie tablicy.

EG, nie działa:

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

Oczywiście mogę to zrobić ręcznie:

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

..ale czy jest lepszy sposób?

mBria
źródło

Odpowiedzi:

298

Użyj metody org.junit.AssertassertArrayEquals :

import org.junit.Assert;
...

Assert.assertArrayEquals( expectedResult, result );

Jeśli ta metoda nie jest dostępna, być może przypadkowo zaimportowano klasę Assert z programu junit.framework.

Andy Thomas
źródło
ale wszystko, co otrzymujesz, gdy zawiedzie przy innej długości, to java.lang.AssertionError: array lengths differed, expected.length=6 actual.length=7. Jak większość komunikatów o błędach JUnit, nie jest to tak pomocne ... Radzę użyć jakiegoś frameworka asercji
user1075613
1
@ user1075613 - Uważam, że jest to pomocne. Stwierdziliśmy, że tablice są równe, a nie, i dano nam wskazówkę, dlaczego. Stamtąd możemy ustawić punkt przerwania i szczegółowo zbadać tablice.
Andy Thomas
1
racja, to - trochę - pomocne. Jednak, jak na to zwracasz uwagę, w chwili, gdy otrzymujesz tę wiadomość, zadajesz sobie pytanie „dlaczego nie jest tej samej długości?” więc chcesz sprawdzić zawartość. Po co tracić czas na debuger, skoro dobry komunikat o błędzie może powiedzieć to bezpośrednio? (pewnie, że czasami potrzebujesz debugera, ale przez większość czasu nie)
user1075613
Możesz przesyłać zgłoszenia do systemu śledzenia problemów JUnit . Należy jednak pamiętać, że 1) szybka awaria w O (1) może być zaletą, 2) wyjście niepowodzenia asercji nie powinno wynosić O (n). System śledzenia problemów JUnit jest lepszym forum do dalszej dyskusji.
Andy Thomas
1
@anddero - Assert.assertFalse( Arrays.equals( expectedResult, result )).
Andy Thomas
35

Możesz użyć Arrays.equals(..):

assertTrue(Arrays.equals(expectedResult, result));
Bozho
źródło
14
Ale to, co w tym śmierdzi, to brak danych o tym, co poszło nie tak, gdy się nie powiedzie.
mBria
8
Fajnie, gdy jesteś na starszej wersji junit (jak na Androidzie)
Zitrax,
2
Jeśli chcesz zobaczyć, które bajty nie pasują, możesz przekonwertować je na string: assertEquals (Arrays.toString (spodziewanyResult), Arrays.toString (wynik));
Erdem
17

Wolę konwertować tablice na ciągi:

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

w ten sposób wyraźnie widzę, gdzie są złe wartości. Działa to skutecznie tylko w przypadku tablic o małych rozmiarach, ale rzadko używam tablic zawierających więcej elementów niż 7 w moich testach jednostkowych.

Ta metoda działa dla typów pierwotnych i dla innych typów, gdy przeciążenie toStringzwraca wszystkie niezbędne informacje.

csharpfolk
źródło
4

Używając junit4 i Hamcrest , otrzymujesz zwięzłą metodę porównywania tablic. Zawiera również szczegółowe informacje o tym, gdzie błąd znajduje się w śledzeniu awarii.

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

//...

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

Wyjście śledzenia awarii:

java.lang.AssertionError: 
   Expected: is [<56>, <100>, <2000>]
   but: was [<55>, <100>, <2000>]
winstanr
źródło
2

Wiem, że pytanie dotyczy JUnit4, ale jeśli utkniesz w JUnit3, możesz utworzyć krótką funkcję narzędzia, taką jak ta:

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

W JUnit3 jest to lepsze niż bezpośrednie porównywanie tablic, ponieważ szczegółowo określa, które elementy są różne.

Haroldo_OK
źródło