Pytanie W jaki sposób można stwierdzić, że pewien wyjątek jest zgłaszany w testach JUnit 4?


Jak używać idiomatycznie JUnit4 do testowania, że ​​jakiś kod zgłasza wyjątek?

Chociaż mogę z pewnością zrobić coś takiego:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  boolean thrown = false;

  try {
    foo.doStuff();
  } catch (IndexOutOfBoundsException e) {
    thrown = true;
  }

  assertTrue(thrown);
}

Przypominam, że istnieje adnotacja lub plik Assert.xyz lub coś to znacznie mniej kludgy i dużo więcej w duchu JUnit w takich sytuacjach.


1624
2017-10-01 06:56


pochodzenie


Problem z jakimkolwiek innym podejściem, ale polega na tym, że niezmiennie kończą test, gdy wyjątek został zgłoszony. Ja, z drugiej strony, często wciąż chcemy dzwonić org.mockito.Mockito.verify z różnymi parametrami, aby upewnić się, że pewne rzeczy się zdarzyły (tak, że usługa rejestratora została wywołana z poprawnymi parametrami) przed wyrzuceniem wyjątku. - ZeroOne
Możesz zobaczyć, jak testować wyjątki na stronie wiki JUnit github.com/junit-team/junit/wiki/Exception-testing - PhoneixS
@ ZeroOne - Do tego chciałbym mieć dwa różne testy - jeden dla wyjątku i jeden dla zweryfikowania interakcji z twoją próbą. - tddmonkey
Jest sposób, aby to zrobić z JUnit 5, zaktualizowałem swoją odpowiedź poniżej. - Dilini Rajapaksha


Odpowiedzi:


JUnit 4 wspiera to:

@Test(expected = IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
    ArrayList emptyList = new ArrayList();
    Object o = emptyList.get(0);
}

Odniesienie: https://junit.org/junit4/faq.html#atests_7


1945
2017-10-01 07:12



Ten fragment kodu nie zadziała, jeśli spodziewasz się wyjątku tylko gdzieś w kodzie, a nie takiego koca. - Oh Chin Boon
@skaffman Nie działałoby to z org.junit.experimental.theories.Theory prowadzone przez org.junit.experimental.theories.Theories - Artem Oboturov
Roy Osherove zniechęca do tego rodzaju testowania wyjątków Sztuka testowania jednostek, ponieważ wyjątek może znajdować się w dowolnym miejscu wewnątrz testu, a nie tylko wewnątrz testowanej jednostki. - Kevin Wittek
Nie zgadzam się z @ Kiview / Roy Osherove. Moim zdaniem, testy powinny dotyczyć zachowania, a nie implementacji. Testując, że określona metoda może wygenerować błąd, wiążesz testy bezpośrednio z implementacją. Twierdzę, że testowanie w powyższej metodzie zapewnia bardziej wartościowy test. Zastrzeżenie, które chciałbym dodać, to to, że w tym przypadku chciałbym przetestować niestandardowy wyjątek, dzięki czemu wiem, że otrzymuję wyjątek, którego naprawdę chcę. - nickbdyer
Ani. Chcę przetestować zachowanie klasy. Ważne jest to, że jeśli próbuję pobrać coś, czego nie ma, otrzymuję wyjątek. Fakt, że struktura danych jest ArrayList na który reaguje get() nie ma znaczenia. Gdybym wybrał w przyszłości przejście na prymitywną tablicę, musiałbym zmienić tę implementację testową. Struktura danych powinna być ukryta, aby test mógł skupić się na zachowaniu klasa. - nickbdyer


Edytować Teraz, gdy JUnit5 został wydany, najlepszą opcją byłoby użycie Assertions.assertThrows() (widzieć moja druga odpowiedź).

Jeśli nie przeprowadziłeś migracji do JUnit 5, ale możesz użyć JUnit 4.7, możesz użyć ExpectedException Reguła:

public class FooTest {
  @Rule
  public final ExpectedException exception = ExpectedException.none();

  @Test
  public void doStuffThrowsIndexOutOfBoundsException() {
    Foo foo = new Foo();

    exception.expect(IndexOutOfBoundsException.class);
    foo.doStuff();
  }
}

To jest znacznie lepsze niż @Test(expected=IndexOutOfBoundsException.class) ponieważ test się nie powiedzie, jeśli IndexOutOfBoundsException jest rzucany wcześniej foo.doStuff()

Widzieć Ten artykuł dla szczegółów


1166
2018-05-29 17:16



@skaffman - Jeśli zrozumiałem to poprawnie, wygląda na to, że wyjątek. Wyjątek jest stosowany tylko w jednym teście, a nie w całej klasie. - bacar
Jeśli wyjątek, który spodziewamy się, że zostanie rzucony, jest sprawdzanym wyjątkiem, czy powinniśmy dodać rzuty lub spróbować złapać lub przetestować tę sytuację w inny sposób? - MJafar Mash
@MartinTrummer Żaden kod nie powinien być uruchamiany po foo.doStuff (), ponieważ wyjątek został zgłoszony i metoda została zakończona. Posiadanie kodu po oczekiwanym wyjątku (z wyjątkiem zamknięcia zasobów w końcu) jest w każdym razie niepomocne, ponieważ nie powinno być wykonywane, jeśli zostanie zgłoszony wyjątek. - Jason Thompson
To najlepsze podejście. Są dwie zalety w porównaniu do rozwiązania skaffmana. Po pierwsze, ExpectedException klasa ma sposoby dopasowywania wiadomości wyjątku, a nawet pisania własnych reguł, które zależą od klasy wyjątków. Po drugie, możesz ustawić swoje oczekiwanie bezpośrednio przed linią kodu, której spodziewasz się rzucić wyjątek - co oznacza, że ​​twój test się nie powiedzie, jeśli zły wiersz kodu zgłasza wyjątek; mając na uwadze, że nie można tego zrobić przy pomocy rozwiązania skaffmana. - Dawood ibn Kareem
@MJafarMash, jeśli sprawdzany jest wyjątek, który chcesz rzucić, dodaj ten wyjątek do klauzuli throws metody testowej. Robisz to samo za każdym razem, gdy testujesz metodę, która jest zadeklarowana, aby wyrzucić sprawdzony wyjątek, nawet jeśli wyjątek nie jest uruchamiany w konkretnym przypadku testowym. - NamshubWriter


Zachowaj ostrożność, używając oczekiwanego wyjątku, ponieważ tylko potwierdza, że metoda rzucił ten wyjątek, nie a konkretna linia kodu w teście.

Zwykle używam tego do testowania poprawności parametrów, ponieważ takie metody są zazwyczaj bardzo proste, ale bardziej złożone testy mogą być lepiej obsługiwane:

try {
    methodThatShouldThrow();
    fail( "My method didn't throw when I expected it to" );
} catch (MyException expectedException) {
}

Zastosuj osąd.


409
2017-10-01 09:31



Może jestem stary, ale nadal wolę to. Daje mi również miejsce do przetestowania samego wyjątku: czasami mam wyjątki z pobierającymi dla pewnych wartości, lub może po prostu szukam konkretnej wartości w wiadomości (np. Szukam "xyz" w komunikacie "nierozpoznany kod" xyz " "). - Rodney Gitzel
Myślę, że podejście NamshubWriter daje ci to, co najlepsze z obu światów. - Eddie
+1 przydatne w niektórych sytuacjach, w których oczekiwane = xx nie pasuje do wymagań. - Oh Chin Boon
Za pomocą ExpectedException można wywołać N wyjątek. Wywołać jedną metodę, aby przetestować jak ten wyjątek.expect (IndexOutOfBoundsException.class); foo.doStuff1 (); exception.expect (IndexOutOfBoundsException.class); foo.doStuff2 (); exception.expect (IndexOutOfBoundsException.class); foo.doStuff3 (); - user1154664
@ user1154664 Właściwie nie możesz. Korzystając z ExpectedException można tylko przetestować, że jedna metoda zgłasza wyjątek, ponieważ po wywołaniu tej metody test przestanie być wykonywany, ponieważ spowodował oczekiwany wyjątek! - NamshubWriter


Jak już wspomniano, istnieje wiele sposobów radzenia sobie z wyjątkami w JUnit. Ale w przypadku Java 8 jest jeszcze jedno: używanie wyrażeń Lambda. W wyrażeniach Lambda możemy uzyskać taką składnię:

@Test
public void verifiesTypeAndMessage() {
    assertThrown(new DummyService()::someMethod)
            .isInstanceOf(RuntimeException.class)
            .hasMessage("Runtime exception occurred")
            .hasMessageStartingWith("Runtime")
            .hasMessageEndingWith("occurred")
            .hasMessageContaining("exception")
            .hasNoCause();
}

assertThrown akceptuje funkcjonalny interfejs, którego wystąpienia można tworzyć za pomocą wyrażeń lambda, odwołań do metod lub odwołań do konstruktora. assertThrown akceptując, że interfejs będzie oczekiwał i będzie gotowy do obsługi wyjątku.

Jest to stosunkowo prosta, ale potężna technika.

Zobacz ten wpis na blogu opisujący tę technikę: http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

Kod źródłowy można znaleźć tutaj: https://github.com/kolorobot/unit-testing-demo/tree/master/src/test/java/com/github/kolorobot/exceptions/java8

Ujawnienie: Jestem autorem bloga i projektu.


189
2017-07-07 22:35



Podoba mi się to rozwiązanie, ale czy mogę pobrać to z repozytorium maven? - Selwyn
@Airuster jedna implementacja tego pomysłu, który jest dostępny na Maven jest stefanbirkner.github.io/vallado - NamshubWriter
Powinny przekazać to jako żądanie pobrania do JUnit ... - Cristiano Fontes
@CristianoFontes prostsza wersja tego API jest przeznaczona dla JUnit 4.13. Widzieć github.com/junit-team/junit/commit/... - NamshubWriter
@RafalBorowiec technicznie, new DummyService()::someMethod jest MethodHandle, ale to podejście działa równie dobrze z wyrażeniami lambda. - Andy


na junit istnieją cztery sposoby testowania wyjątku.

  • dla junit4.x użyj opcjonalnego "oczekiwanego" atrybutu annonacji testu

    @Test(expected = IndexOutOfBoundsException.class)
    public void testFooThrowsIndexOutOfBoundsException() {
        foo.doStuff();
    }
    
  • dla junit4.x użyj reguły ExpectedException

    public class XxxTest {
        @Rule
        public ExpectedException thrown = ExpectedException.none();
    
        @Test
        public void testFooThrowsIndexOutOfBoundsException() {
            thrown.expect(IndexOutOfBoundsException.class)
            //you can test the exception message like
            thrown.expectMessage("expected messages");
            foo.doStuff();
        }
    }
    
  • możesz również użyć klasycznej metody try / catch powszechnie używanej w ramach junit 3

    @Test
    public void testFooThrowsIndexOutOfBoundsException() {
        try {
            foo.doStuff();
            fail("expected exception was not occured.");
        } catch(IndexOutOfBoundsException e) {
            //if execution reaches here, 
            //it indicates this exception was occured.
            //so we need not handle it.
        }
    }
    
  • na końcu dla junit5.x możesz również użyć assertThrows w następujący sposób

    @Test
    public void testFooThrowsIndexOutOfBoundsException() {
        Throwable exception = assertThrows(IndexOutOfBoundsException.class, () -> foo.doStuff());
        assertEquals("expected messages", exception.getMessage());
    }
    
  • więc

    • Pierwsza metoda jest używana, gdy chcesz przetestować typ wyjątku
    • pozostałe trzy sposoby są używane, gdy chcesz otrzymać wyjątek testowy
    • jeśli używasz junit 3, preferowany jest trzeci
    • jeśli lubisz junit 5, powinieneś polubić czwartą
  • aby uzyskać więcej informacji, możesz przeczytać ten dokument i Przewodnik użytkownika junit5 dla szczegółów.


84
2017-08-05 08:05



Dla mnie jest to najlepsza odpowiedź, obejmuje wszystko bardzo wyraźnie, dzięki! Osobiście nadal używam trzeciej opcji, nawet z Junit4 dla czytelności, aby uniknąć pustego bloku blokującego można również złapać Throwable i potwierdzić typ e - Nicolas Cornette
Czy można użyć wyjątku ExpectedException, aby oczekiwać sprawdzonego wyjątku? - miuser
Wszystko to jest nagromadzenie trzech najlepszych odpowiedzi. IMO, ta odpowiedź nie powinna była zostać opublikowana, jeśli nie dodaje nic nowego. Odpowiadanie (popularne pytanie) dla przedstawiciela. Dość bezużyteczne. - Paul Samsotha
z pewnością, ponieważ możesz przekazać dowolny typ pochodzący z Trowable do metody ExpectedException.expect. proszę zobaczyć to jest podpis. @miuser - walsh


tl; dr

  • pre-JDK8: Polecę stare dobro try-catch blok.

  • post-JDK8: użyj AssertJ lub niestandardowych lambdas do potwierdzenia wyjątkowy zachowanie.

Niezależnie od Junit 4 lub JUnit 5.

długa historia

Możliwe jest napisanie siebie Zrób to sam  try-catch blokować lub używać narzędzi JUnit (@Test(expected = ...) albo @Rule ExpectedException Funkcja JUnit).

Ale te sposoby nie są tak eleganckie i nie mieszają się dobrze czytelność z innymi narzędziami.

  1. The try-catch blokuj, musisz napisać blok wokół testowanego zachowania i napisać asercję w bloku catch, co może być w porządku, ale wielu odkrywa, że ​​ten styl przerywa przepływ odczytu testu. Musisz również napisać Assert.fail na końcu try w przeciwnym wypadku test może pominąć jedną stronę twierdzeń; PMD, findbugs lub Sonar dostrzeże takie problemy.

  2. The @Test(expected = ...) funkcja jest interesująca, ponieważ można napisać mniej kodu, a następnie napisanie tego testu jest rzekomo mniej podatne na błędy kodowania. Ale w tym podejściu brakuje niektórych obszarów.

    • Jeśli test musi sprawdzić dodatkowe rzeczy na wyjątku, takie jak przyczyna lub wiadomość (dobre wiadomości wyjątków są naprawdę ważne, posiadanie dokładnego typu wyjątku może nie być wystarczające).
    • Również w metodzie, w zależności od tego, w jaki sposób testowany kod jest zapisany, oczekiwana jest oczekiwana metoda, więc niewłaściwa część kodu testowego może wyrzucić wyjątek, prowadząc do fałszywie dodatniego testu i nie jestem pewien, czy PMD, findbugs lub Sonar poda wskazówki dotyczące takiego kodu.

      @Test(expected = WantedException.class)
      public void call2_should_throw_a_WantedException__not_call1() {
          // init tested
          tested.call1(); // may throw a WantedException
      
          // call to be actually tested
          tested.call2(); // the call that is supposed to raise an exception
      }
      
  3. The ExpectedException zasada jest także próbą naprawienia poprzednich zastrzeżeń, ale korzystanie z niej jest nieco niewygodne, ponieważ wykorzystuje styl oczekiwania, EasyMock użytkownicy bardzo dobrze znają ten styl. Dla niektórych może to być wygodne, ale jeśli podążysz za nim Zachowanie napędzane zachowaniem (BDD) lub Arrange Act Assert (AAA) zasady ExpectedException zasada nie pasuje do tego stylu pisania. Poza tym może cierpieć z tego samego problemu, co w przypadku @Test sposób, w zależności od miejsca, w którym stawiasz oczekiwanie.

    @Rule ExpectedException thrown = ExpectedException.none()
    
    @Test
    public void call2_should_throw_a_WantedException__not_call1() {
        // expectations
        thrown.expect(WantedException.class);
        thrown.expectMessage("boom");
    
        // init tested
        tested.call1(); // may throw a WantedException
    
        // call to be actually tested
        tested.call2(); // the call that is supposed to raise an exception
    }
    

    Nawet oczekiwany wyjątek jest umieszczany przed instrukcją testową, łamie przepływ czytania, jeśli testy są zgodne z BDD lub AAA.

    Zobacz także to komentarz numer na JUnit autora ExpectedException.

Tak więc powyższe opcje mają cały swój limit zastrzeżeń i wyraźnie nie są odporne na błędy koderów.

  1. Jest projekt, który uzyskałem świadomość po utworzeniu tej odpowiedzi, która wygląda obiecująco, jest wyjątek catch.

    Jak mówi opis projektu, pozwala on programistce pisać w płynnym wierszu kodu wychwytującego wyjątek i oferować ten wyjątek dla późniejszego potwierdzenia. I możesz użyć dowolnej biblioteki asercji, takiej jak Hamcrest lub AssertJ.

    Szybki przykład zaczerpnięty ze strony głównej:

    // given: an empty list
    List myList = new ArrayList();
    
    // when: we try to get the first element of the list
    when(myList).get(1);
    
    // then: we expect an IndexOutOfBoundsException
    then(caughtException())
            .isInstanceOf(IndexOutOfBoundsException.class)
            .hasMessage("Index: 1, Size: 0") 
            .hasNoCause();
    

    Jak widać kod jest naprawdę prosty, przechwytujesz wyjątek w konkretnej linii, czyli then API to alias, który będzie korzystać z API AssertJ (podobnie jak przy użyciu assertThat(ex).hasNoCause()...). W pewnym momencie projekt polegał na FEST-Assert przodku AssertJ. EDYTOWAĆ: Wygląda na to, że projekt przygotowuje wsparcie dla Java 8 Lambdas.

    Obecnie biblioteka ma dwa braki:

    • W chwili pisania tego tekstu warto zauważyć, że biblioteka ta bazuje na Mockito 1.x, ponieważ tworzy ona symulację badanego obiektu za sceną. Ponieważ Mockito wciąż nie jest aktualizowany ta biblioteka nie może działać z końcowymi klasami lub ostatecznymi metodami. I nawet gdyby był oparty na mockito 2 w obecnej wersji, wymagałoby to deklaracji globalnego twórcy próbnego (inline-mock-maker), coś, co może nie być tym, czego chcesz, jako że ta kreślarz ma inne wady niż zwykły szewc.

    • Wymaga to innej zależności testowej.

    Problemy te nie będą miały zastosowania, gdy biblioteka będzie obsługiwać lambdy, jednak funkcjonalność zostanie zduplikowana przez zestaw narzędzi AssertJ.

    Biorąc wszystko pod uwagę, jeśli nie chcesz korzystać z narzędzia wyjątku catch, polecam stary dobry sposób try-catch blokować, przynajmniej do JDK7. A dla użytkowników JDK 8 możesz preferować użycie AssertJ, ponieważ oferuje więcej niż tylko potwierdzanie wyjątków.

  2. Wraz z JDK8, lambdas wchodzi na scenę testową i okazały się interesującym sposobem na potwierdzenie wyjątkowego zachowania. AssertJ został zaktualizowany w celu zapewnienia płynnego interfejsu API, który zapewnia wyjątkowe zachowanie.

    I próbny test z AssertJ :

    @Test
    public void test_exception_approach_1() {
        ...
        assertThatExceptionOfType(IOException.class)
                .isThrownBy(() -> someBadIOOperation())
                .withMessage("boom!"); 
    }
    
    @Test
    public void test_exception_approach_2() {
        ...
        assertThatThrownBy(() -> someBadIOOperation())
                .isInstanceOf(Exception.class)
                .hasMessageContaining("boom");
    }
    
    @Test
    public void test_exception_approach_3() {
        ...
        // when
        Throwable thrown = catchThrowable(() -> someBadIOOperation());
    
        // then
        assertThat(thrown).isInstanceOf(Exception.class)
                          .hasMessageContaining("boom");
    }
    
  3. Z prawie kompletnym przeróbką JUnit 5, pojawiły się twierdzenia ulepszony Nieco, mogą okazać się interesujące, jak po wyjęciu z pudełka, aby potwierdzić właściwy wyjątek. Ale tak naprawdę API twierdzenia jest wciąż słabe, nie ma nic na zewnątrz assertThrows.

    @Test
    @DisplayName("throws EmptyStackException when peeked")
    void throwsExceptionWhenPeeked() {
        Throwable t = assertThrows(EmptyStackException.class, () -> stack.peek());
    
        Assertions.assertEquals("...", t.getMessage());
    }
    

    Jak zauważyłeś assertEquals wciąż wraca voidi jako taki nie pozwala na łańcuchowe twierdzenia, takie jak AssertJ.

    Również, jeśli pamiętasz nazwę, koliduj z Matcher lub Assert, przygotuj się na spotkanie z tym samym zderzeniem Assertions.

Chciałbym stwierdzić, że dzisiaj (2017-03-03) AssertJłatwość użycia, wykrywalny interfejs API, szybkie tempo rozwoju i jako de facto zależność testowa jest najlepszym rozwiązaniem z JDK8 niezależnie od frameworka testowego (JUnit lub nie), wcześniejsze pakiety JDK powinny polegać na try-catch blokuje, nawet jeśli czują się niepewnie.

Ta odpowiedź została skopiowana z inne pytanie które nie mają tej samej widoczności, jestem tym samym autorem.


58
2017-12-07 14:19



Dodanie org.junit.jupiter: junit-jupiter-engine: zależność 5.0.0-RC2 (oprócz już istniejącej junit: junit: 4.12), aby móc używać assertThrows, być może nie jest preferowanym rozwiązaniem, ale nie spowodowało żadnego problemy dla mnie. - anre
Jestem fanem używania reguły ExpectedException, ale zawsze mi przeszkadzało, że zrywa z AAA. Napisałeś doskonały artykuł opisujący wszystkie różne podejścia i zdecydowanie zachęciłeś mnie do wypróbowania AssertJ :-) Dzięki! - Pim Hazebroek
@PimHazebroek dzięki. Interfejs API AssertJ jest dość bogaty. Lepsze w mojej opinii, co JUnit proponuje po wyjęciu z pudełka. - Brice


BDD Rozwiązanie w stylu: JUnit 4 + Catch Exception + AssertJ

@Test
public void testFooThrowsIndexOutOfBoundsException() {

    when(foo).doStuff();

    then(caughtException()).isInstanceOf(IndexOutOfBoundsException.class);

}

Kod źródłowy

Zależności

eu.codearte.catch-exception:catch-exception:1.3.3

31
2017-11-15 19:17





Co powiesz na to: Złap wyjątek bardzo ogólny, upewnij się, że wychodzi z bloku catch, a następnie upewnij się, że klasa wyjątku jest tym, czego oczekujesz. To potwierdzenie nie powiedzie się, jeśli: a) wyjątek jest niewłaściwego typu (np. Jeśli zamiast niego pojawił się Null Pointer) oraz b) wyjątek nigdy nie został zgłoszony.

public void testFooThrowsIndexOutOfBoundsException() {
  Throwable e = null;

  try {
    foo.doStuff();
  } catch (Throwable ex) {
    e = ex;
  }

  assertTrue(e instanceof IndexOutOfBoundsException);
}

30
2017-10-01 07:03



To właśnie robisz w JUnit 3. Junit 4 robi to lepiej. - skaffman
Ponadto, nie zobaczysz, jaki rodzaj wyjątku ex jest w wynikach testu, gdy nadejdzie dzień, w którym test się nie powiedzie. - jontejj


Korzystanie z AssertJ asercja, która może być używana wraz z JUnit:

import static org.assertj.core.api.Assertions.*;

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  Foo foo = new Foo();

  assertThatThrownBy(() -> foo.doStuff())
        .isInstanceOf(IndexOutOfBoundsException.class);
}

To jest lepsze niż @Test(expected=IndexOutOfBoundsException.class)ponieważ gwarantuje, że oczekiwana linia w teście rzuciła wyjątek i umożliwia sprawdzenie dodatkowych szczegółów dotyczących wyjątku, takich jak wiadomości, łatwiej:

assertThatThrownBy(() ->
       {
         throw new Exception("boom!");
       })
    .isInstanceOf(Exception.class)
    .hasMessageContaining("boom");

Instrukcje Maven / Gradle tutaj.


30
2018-03-05 11:07



najbardziej zwięzły sposób i nikt tego nie docenia, dziwne .. Mam tylko jeden problem z biblioteką assertJ, assertThat jest konfliktem pod nazwą junit. więcej o aserJ throwby: JUnit: Testowanie wyjątków w Javie 8 i AssertJ 3.0.0 ~ Codeleak.pl - ycomp
@Comp Cóż, jest to nowa odpowiedź na bardzo stare pytanie, więc różnica wyniku jest zwodnicza. - weston
To prawdopodobnie najlepsze rozwiązanie, jeśli można używać Java 8 i AssertJ! - Pierre Henry
@ycomp Podejrzewam, że konflikt nazw może być zgodny z projektem: dlatego biblioteka AssertJ zdecydowanie zachęca do tego, aby nigdy nie używać JUnit assertThat, zawsze AssertJ. Również metoda JUnit zwraca tylko typ "regularny", podczas gdy metoda AssertJ zwraca wartość AbstractAssert podklasa ... umożliwiająca przeciąganie metod jak powyżej (lub jakiekolwiek inne warunki techniczne są dla tego ...). - mike rodent
@weston faktycznie właśnie użyłem twojej techniki w AssertJ 2.0.0. Bez wątpienia nie ma usprawiedliwienia dla ulepszenia, ale mimo to chciałbyś wiedzieć. - mike rodent


Aby rozwiązać ten sam problem, przygotowałem mały projekt: http://code.google.com/p/catch-exception/

Używając tego małego pomocnika napiszesz

verifyException(foo, IndexOutOfBoundsException.class).doStuff();

Jest to mniej szczegółowe niż zasada Expected Exception JUnit 4.7. W porównaniu do rozwiązania dostarczanego przez skaffman, możesz określić, w której linii kodu spodziewasz się wyjątku. Mam nadzieję, że to pomoże.


29
2017-10-28 09:26



Pomyślałem również o zrobieniu czegoś podobnego, ale ostatecznie odkryłem, że prawdziwą potęgą ExpectedException jest to, że nie tylko możesz określić oczekiwany wyjątek, ale możesz również określić pewne właściwości wyjątku, takie jak oczekiwana przyczyna lub oczekiwany komunikat. - Jason Thompson
możesz to również zrobić za pomocą catchException - Martin Trummer
Domyślam się, że to rozwiązanie ma kilka takich samych wad, jak mocks? Na przykład, jeśli foo jest final to się nie powiedzie, bo nie możesz proxy foo? - Tom
Tom, jeśli doStuff () jest częścią interfejsu, podejście proxy będzie działało. W przeciwnym razie to podejście zakończy się niepowodzeniem, masz rację. - rwitzel