2223 votes

Comment avez-vous affirmer qu'un certain exception est levée dans JUnit 4 tests?

Comment puis-je utiliser JUnit4 idiomatique pour tester du code déclenche une exception?

Bien que je ne peux certainement faire quelque chose comme ceci:

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

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

  assertTrue(thrown);
}

Je me souviens qu'il y a une annotation ou une Assertion.xyz ou quelque chose qui est beaucoup moins encombrants et bien plus dans l'esprit de JUnit pour ces sortes de situations.

2524voto

skaffman Points 197885

JUnit 4 a l'appui de ceci:

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

1404voto

NamshubWriter Points 7238

Si vous pouvez utiliser JUnit 4.7, vous pouvez utiliser l' ExpectedException Règle

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

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

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

C'est beaucoup mieux que @Test(expected=IndexOutOfBoundsException.class) parce que le test échoue si l' IndexOutOfBoundsException sont lancés avant foo.doStuff()

Voir cet article pour plus de détails

500voto

daveb Points 24831

Soyez prudent en utilisant ce devrait exception, car il affirme que la méthode a jeté cette exception, pas une ligne de code dans le test.

J'ai tendance à l'utiliser pour les tests de validation de paramètre, parce que ces méthodes sont généralement très simple, mais plus complexe de tests peut être mieux servi avec:

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

Appliquer le jugement.

221voto

Rafal Borowiec Points 406

Comme répondu précédemment, il existe de nombreuses façons de composer avec des exceptions dans JUnit. Mais avec Java 8, il y en a une autre: l'utilisation des Expressions Lambda. Avec les Expressions Lambda, nous pouvons réaliser une syntaxe comme celle-ci:

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

assertThrown accepte une interface fonctionnelle, les instances qui peuvent être créés avec les expressions lambda, la méthode des renvois ou références constructeur. assertThrown accepter que l'interface allons attendre et être prêt à gérer une exception.

C'est relativement simple, mais puissante technique.

Jetez un oeil à ce blog décrivant cette technique: http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

Le code source peut être trouvé ici: https://github.com/kolorobot/unit-testing-demo/tree/master/src/test/java/com/github/kolorobot/exceptions/java8

33voto

rwoo Points 515

Pour résoudre le même problème, je n'ai mis en place un petit projet: http://code.google.com/p/catch-exception/

À l'aide de ce petit assistant vous l'écrire

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

C'est moins détaillé que le ExpectedException règle de JUnit 4.7. En comparaison à la solution fournie par skaffman, vous pouvez spécifier dans la ligne de code que vous attendez de l'exception. J'espère que cette aide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X