2011-08-12 7 views
5

Mam kilka metod powracających HashSet. Chciałbym, aby mój test jednostkowy sprawdził stan tych obiektów, tj. Potwierdził, że someObject.getName() == "foobar".HashSet w jednostce testuje

Jednak kolejność HashSet iterator nie jest gwarantowana, więc moje testy jednostkowe nie kilka razy. Jak pisać testy jednostkowe dla czegoś takiego?

Np

@Test 
    public void testRowsToBeRead(){ 
     HashSet<SomeObject> rows = new SomeObject().read(); 
     assertEquals(19, rows.size()); 

     for(SomeObject r:rows){ 
      //How do I confirm contents? 
     } 
    } 

myślę, że przyjąłem odpowiedź zbyt szybko.

Problem mam teraz jest, że wdrożyliśmy metody equals, który sprawdza tylko dla 2 pól w obiekt za projekt (jest to naśladowanie tabelę DB). Jednak w moim badanej jednostki, chcę sprawdzić wszystkich dziedzinach, takich jak opis itp, które nie jest w moich rówieśników. Jeśli więc 2 pola zostaną zamienione, a te pola nie są w mojej równej wersji, to test jednostkowy daje fałszywy alarm.

Odpowiedz

4

Moje podejście:

public void testRowsToBeRead(){ 
    HashSet<SomeObject> expectedRows = new HasSet<SomeObject(); 
    expectedRows.add(new SomeObject("abc")); 
    expectedRows.add(new SomeObject("def")); 

    HashSet<SomeObject> rows = new SomeObject().read(); 

    // alternative 1 
    assertEquals(19, rows.size()); 

    for(SomeObject r:rows){ 
     if (!expectedRows.contains(r)) { 
      // test failed 
     } 
    } 

    // alternative 2 
    assertTrue(expectedRows.equals(rows)); 
} 

Aby powoływać się na ten test może być konieczne inne testy jednostkowe potwierdzających SomeObject „s equals i hashCode metody działają tak jak powinny ...

EDIT na podstawie jeden z twoich komentarzy

Jeśli chcesz sprawdzić pola, które nie są częścią umowy equals, musisz wykonać iterację przez t postawił:

public void testRowsToBeRead(){ 
    HashSet<SomeObject> expectedRows = new HasSet<SomeObject(); 
    expectedRows.add(new SomeObject("a", "a1")); 
    expectedRows.add(new SomeObject("b", "b1")); 

    HashSet<SomeObject> rows = new SomeObject().read(); 

    for(SomeObject r : rows) { 
     SomeObject expected = expectedRows.get(r); // equals and hashCode must still match 

     if (expected == null) { 
      // failed 
     } 

     if (!expected.getField1().equals(r.getField1()) && !expected.getField2().equals(r.getField2())) { 
      // failed 
     } 
    } 
} 

W powyższym przykładzie SomeObject „s equals może wyglądać tak, a jedynie sprawdza field1:

@Override 
public boolean equals(Object other) { 
    return this.getField1().equals(((SomeObject) other).getField1()); 
} 

Bez wątpienia, w zależności od konkretnego przypadku zastosowania tego mogą stać się bardziej złożone . Nadzieję, że to pomaga ...

+1

'tak samo' i 'hashCode' muszą być zaimplementowane poprawnie, aby użyć tego podejścia (i użyć HashSet). – Genzer

+0

@Genzer: Ups, dziękuję, masz rację. Zaktualizowałem odpowiedź ... – home

+0

Mam już testy jednostek równych i kodów kreskowych, więc myślę, że to daje mi dokładnie to, czego szukam. – Kapsh

2

Można użyć LinkedHashSet które gwarantują porządek.

+0

Dzięki. To wymaga zmiany aktualnej metody. Mogę to kiedyś zrobić w przyszłości, ale teraz szukam tylko testu jednostkowego. – Kapsh

2

spróbuje użyć assertThat:

Assert.assertThat(r.getName(), AnyOf.anyOf(Is.is("foobar1"), Is.is("foobar2"), ...)); 
2

Można użyć Assert.assertEquals() na prawie każdej kolekcji z TestNG i prawdopodobnie JUnit również.

Jeśli chcesz rzucić to samodzielnie, usuń wszystkie elementy zestawu rzeczywistego z oczekiwanego zestawu i upewnij się, że oczekiwany rozmiar zestawu wynosi zero, gdy skończysz.

1

Polecam korzystanie HashSet.equals(Object).

JavaDoc mówi:

Ta realizacja najpierw sprawdza, czy określony obiekt jest ten zestaw; jeśli tak, zwraca true. Następnie sprawdza, czy określony obiekt jest zbiorem, którego rozmiar jest identyczny z rozmiarem tego zestawu; jeśli nie, zwraca wartość false. Jeśli tak, to zwraca containsAll ((Collection) o).

Uważam, że wystarczy "alternatywa 2" w domu.

plus: Chociaż HashSet nie gwarantuje zamówienia, to jednak ustawiony zestaw HashSet ma tę samą kolejność i rozmiar.