CollectionAssert in jUnit?

Respostas:

125

Usando JUnit 4.4, você pode usar assertThat()junto com o código Hamcrest (não se preocupe, ele é fornecido com JUnit, sem necessidade de um extra .jar) para produzir declarações autoexplicativas complexas, incluindo aquelas que operam em coleções:

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.*;
import static org.hamcrest.CoreMatchers.*;

List<String> l = Arrays.asList("foo", "bar");
assertThat(l, hasItems("foo", "bar"));
assertThat(l, not(hasItem((String) null)));
assertThat(l, not(hasItems("bar", "quux")));
// check if two objects are equal with assertThat()

// the following three lines of code check the same thing.
// the first one is the "traditional" approach,
// the second one is the succinct version and the third one the verbose one 
assertEquals(l, Arrays.asList("foo", "bar")));
assertThat(l, is(Arrays.asList("foo", "bar")));
assertThat(l, is(equalTo(Arrays.asList("foo", "bar"))));

Usando essa abordagem, você obterá automagicamente uma boa descrição da declaração quando ela falhar.

Joachim Sauer
fonte
1
Ooh, eu não tinha percebido que hamcrest tinha entrado na distro junit. Go Nat!
Skaffman
Se eu quiser afirmar que l é composto de itens ("foo", "bar"), mas não existe nenhum outro item - existe alguma sintaxe fácil para isso?
ripper234
Use o snippet de código acima e acrescente um assertTrue (l.size () == 2)
aberrant80
4
Meh, feio. Em NUnit, isso é CollectionAssert.AreEqual (coleção esperada, coleção atual);
ripper234
1
O Google encontrou outra resposta Stackoverflow que eu estava procurando!
Mykola Golubyev
4

Não diretamente, não. Eu sugiro o uso de Hamcrest , que fornece um rico conjunto de regras de correspondência que se integra perfeitamente com jUnit (e outras estruturas de teste)

skaffman
fonte
Isso não é compilado por algum motivo (consulte stackoverflow.com/questions/1092981/hamcrests-hasitems ): ArrayList <Integer> real = new ArrayList <Integer> (); ArrayList <Integer> esperado = novo ArrayList <Integer> (); actual.add (1); esperado.adicionar (2); assertThat (real, hasItems (esperado));
ripper234
2

Dê uma olhada em FEST Fluent Assertions. IMHO eles são mais convenientes de usar do que Hamcrest (e igualmente poderosos, extensíveis, etc.) e têm melhor suporte IDE graças à interface fluente. Consulte https://github.com/alexruiz/fest-assert-2.x/wiki/Using-fest-assertions

Tomek Kaczanowski
fonte
Em 2017, parece que mais pessoas estão usando um ramo do FEST chamado AssertJ.
Máx.
2

A solução de Joachim Sauer é boa, mas não funciona se você já tem um conjunto de expectativas que deseja verificar em seu resultado. Isso pode surgir quando você já tem uma expectativa gerada ou constante em seus testes com a qual deseja comparar um resultado, ou talvez você tenha várias expectativas que espera que sejam mescladas no resultado. Então, em vez de usar matchers, você pode apenas usar List::containsAlle assertTruePor exemplo:

@Test
public void testMerge() {
    final List<String> expected1 = ImmutableList.of("a", "b", "c");
    final List<String> expected2 = ImmutableList.of("x", "y", "z");
    final List<String> result = someMethodToTest(); 

    assertThat(result, hasItems(expected1)); // COMPILE ERROR; DOES NOT WORK
    assertThat(result, hasItems(expected2)); // COMPILE ERROR; DOES NOT WORK

    assertTrue(result.containsAll(expected1));  // works~ but has less fancy
    assertTrue(result.containsAll(expected2));  // works~ but has less fancy
}
gavs
fonte
Você sempre pode usar hasItems(expected1.toArray(new String[expected1.size()])). Isso lhe dará melhores mensagens de falha.
meustrus