2013-08-21 4 views
5

Chcę przetestować metodę mock nazywany jest w porządku przy użyciu różnych parametrów:Mockito: Jak sprawdzić jedną metodę nazywa się po jednej makiety z innego parametru w celu

Próbowałem użyć następującego kodu:

InOrder inOrder = inOrder(myobject); 
    inOrder.verify(myobject).println(any(String.class)); 
    inOrder.verify(myobject).println(any(String.class)); 
    inOrder.verify(myobject).println(""); 
    inOrder.verify(myobject).println("myfolder"); 
    inOrder.verify(myobject).println(""); 
    inOrder.verify(myobject).println(System.getProperty("user.home")); 

jednak to nie wydają się działać, ponieważ dało mi błąd mówi

inOrder.verify(myobject).println(any(String.class)); 

został powołany do 8 razy. Jest to poprawne, ale nie odnosi się do zamówienia.

Chcę sprawdzić:

The println method of `myobject` is first called with any string parameter 
    Then it is called with any string parameter again 
    Then it is called by an empty string 
    Then it is called by string "myfolder" 
    ...... 

W jaki sposób można to osiągnąć?

EDIT:

Komunikat o błędzie jest:

org.mockito.exceptions.verification.VerificationInOrderFailure: 
Verification in order failure: 
printWriter.println(<any>); 
Wanted 1 time: 
-> at com.mycompany.MyUnitTest.mytest(MyrUnitTest.java:107) 
But was 8 times. 
+0

Czy możesz pokazać nam dokładnie, co mówi błąd? –

+0

Dzięki. Dodano komunikat o błędzie. – KKKCoder

+0

Czy próbowałeś wywoływać go z 'inOrder.verify (myobject, times (2)). Println (any (String.class));'? –

Odpowiedz

5

Użyj przechwytywacza argumentów, aby przechwycić argumenty we wszystkich wywołaniach println, a następnie sprawdź każdą z przechwyconych wartości, które Cię interesują.

@Captor ArgumentCaptor<String> stringCaptor; 

// ... 

@Test public void myTest() { 

    // ... 

    verify(myobject, 6).println(stringCaptor.capture()); 
    assertEquals("", stringCaptor.getAllValues()[2]); 
    assertEquals("myfolder", stringCaptor.getAllValues()[3]); 
    assertEquals("", stringCaptor.getAllValues()[4]);  
    assertEquals(System.getProperty("user.home"), stringCaptro.getAllValues()[5]); 
1

Cóż, odpowiedź nie jest zbyt ogólny i nie jest eleganckie albo.

Dla mnie wygląda na to, że problem spowodowany jest przez any(String.class) jest chciwy, to znaczy pasuje do wszystkich rodzajów ciągów. Tak więc, próbowałem skonstruować matcher, który pasuje do wszystkich rodzajów strun z wyjątkiem kilku wyjątków: "" or "myfolder" or System.getProperty("user.home"). A kod jest:

import static org.mockito.AdditionalMatchers.*; 

inOrder.verify(myobject, times(2)).println(
      and(anyString(), not(
        or(eq(""), or(eq("myfolder"), eq(System.getProperty("user.home"))))))); 

To samo w sobie jest wyzwaniem do formatowania to być czytelny (z jakiegoś tajemniczego powodu, nie mogę nawet wydobyć and(...) do zmiennej lokalnej, ponieważ powoduje dziwny wyjątek czasu wykonywania z Mockito że nie może korzystać z Matchera poza krępowaniem lub weryfikacją).

3

Rozwiązanie Davida Wallace'a jest najlepsze, o którym wiem, że używa Mockito, ale pamiętaj, że szyderstwo nie zawsze jest właściwym narzędziem do tej pracy.

Jeśli możesz, zamiast udawać, przepuścić PrintWriter(ByteArrayOutputStream) i sprawdzić, czy ByteArrayOutputStream odpowiada oczekiwanemu wynikowi.

@Test public void yourTest() { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    PrintWriter writer = new PrintWriter(baos); 
    systemUnderTest.doThing(writer); 

    assertTrue(writer.toString().endsWith(
     "\n\nmyfolder\n\n" + System.getProperty(user.home) + "\n")); 
} 

Jest to również prawdopodobnie bliżej logiki jesteś rzeczywiście testowych, które jest, że wyjście wygląda tak, jak można się spodziewać, że metody nie nazywano we właściwym porządku. Możesz dowolnie modyfikować obraz w dowolny sposób, włączając w to zmianę szablonu na MessageFormatter lub tworzenie nowych linii w StringBuilder i jednorazowe wywołanie println. Jesteś również odizolowany od każdego, kto używa jakiegokolwiek innego połączenia print lub println(), które w przeciwnym wypadku spowodowałoby test oparty na Mockito.

Możesz również użyć wyrażeń regularnych Pattern lub Scanner, aby zweryfikować poprawność, w zależności od konkretnych potrzeb. Pattern.quote może pomóc ci w uniknięciu fragmentów regex, jeśli chcesz programowo zbudować oczekiwany ciąg znaków (tak jak w przypadku user.home tutaj).

+0

+1 Ten test mógłby być napisany bardzo ładnie z interfejsem JMockit Verifications API, ale w końcu jest to przypadek kpiny z nadmiernego użycia; przechwytywanie pełnego ciągu wyjściowego i sprawdzenie, czy jest dobrze uformowane, być może z wyrażeń regularnych, jest znacznie lepszym rozwiązaniem. –