web-dev-qa-db-fra.com

Type d'exception JUnit 4 attendue

J'essaie de faire un test JUnit sur du code que quelqu'un d'autre a écrit, mais je ne peux pas comprendre comment tester l'exception, car l'exception semble manquer de type.

public Pirate(String name, int initialGold) throws Exception {
    if(initialGold < 0)
        throw new Exception("Init Gold must be >= 0");
    this.name = name;
    this.numGold = initialGold;
    this.health = Pirate.DEFAULT_HEALTH;
    this.isCursed = false;
}

Mon extrait de code JUnit:

@Test
public static void constructorTest() throws Exception{
    rodgers = new Pirate("Dread Pirate Rodgers", 10000);
    assertEquals("Dread Pirate Rodgers" , rodgers.getName());
    assertEquals(10000, rodgers.getNumGold());
    assertEquals(100, rodgers.getHealth());
    assertEquals(false, rodgers.getIsCursed());
}

@Test()
public static void exceptionTest() throws Exception{
    rodgers = new Pirate("Dread Pirate Rodgers" , -100);

}

Je sais que je dois mettre attendu = (un certain type d'exception) entre parenthèses de test, mais je ne sais pas quel type d'exception.

34
Marshall Tigerus

Il existe en fait une alternative à la @Test(expected=Xyz.class) dans JUnit 4.7 en utilisant Rule et ExpectedException

Dans votre cas de test, vous déclarez un ExpectedException annoté avec @Rule, Et lui affectez une valeur par défaut de ExpectedException.none(). Ensuite, dans votre test qui attend une exception, vous remplacez la valeur par la valeur réelle attendue. L'avantage de ceci est que sans utiliser la méthode laide try/catch, vous pouvez spécifier davantage le message dans l'exception.

@Rule public ExpectedException thrown= ExpectedException.none();

@Test
public void myTest() {
    thrown.expect( Exception.class );
    thrown.expectMessage("Init Gold must be >= 0");

    rodgers = new Pirate("Dread Pirate Rodgers" , -100);
}

En utilisant cette méthode, vous pourrez peut-être tester que le message dans l'exception générique est quelque chose de spécifique.

[~ # ~] ajout [~ # ~] Un autre avantage de l'utilisation de ExpectedException est que vous pouvez plus précisément définir l'étendue de l'exception dans le contexte du cas de test. Si vous utilisez uniquement l'annotation @Test(expected=Xyz.class) sur le test, l'exception Xyz peut être levée n'importe où dans le code de test - y compris toute configuration de test ou pré-assertions dans la méthode de test. Cela peut conduire à un faux positif.

En utilisant ExpectedException, vous pouvez différer la spécification de la thrown.expect(Xyz.class) jusqu'à la fin de toute configuration et pré-assertion, juste avant d'invoquer réellement la méthode en cours de test. Par conséquent, vous définissez plus précisément l'exception à lever par l'invocation de la méthode réelle plutôt que par le dispositif de test lui-même.

JUnit 5 REMARQUE:

JUnit 5 JUnit Jupiter a supprimé @Test(expected=...), @Rule Et ExpectedException au total. Ils sont remplacés par le nouveau assertThrows() , qui nécessite l'utilisation de Java 8 et la syntaxe lambda. ExpectedException est toujours disponible pour JUnit 5 à JUnit Vintage. JUnit Jupiter continuera également à prendre en charge JUnit 4 ExpectedException en utilisant le module junit-jupiter-migrationsupport , mais uniquement si vous ajoutez un annotation au niveau de la classe de @EnableRuleMigrationSupport .

106
Kevin Welker

Vous pouvez soit utiliser attend dans @ Test annotation o fournir un bloc catch explicite et émettre un échec si le programme le débit n'est pas comme prévu.

@Test(expected=Exception.class) // Java.lang.Exception
public static void exceptionTest() throws Exception {
    rodgers = new Pirate("Dread Pirate Rodgers" , -100);
}

@Test
public static void exceptionTest() throws Exception {
    try {
        rodgers = new Pirate("Dread Pirate Rodgers" , -100);
        fail("should not reach this");
    } catch(Exception e) {
        // ok
    }
}

Ma préférence personnelle est la première solution.

20
Steve Oh

Vous pouvez utiliser JUnit "attendu" pour tester les exceptions:

@Test(expected = ExceptionYouWishToTestFor.class)  
public void divisionWithException() {  
    // Test Code
}

Après cela, c'est à vous de lancer cette exception particulière dans votre code.

9
Michael W

Je ne lancerais pas un Exception si l'or n'est pas supérieur ou égal à zéro. Je lancerais un IllegalArgumentException. Il semble certainement qu'il soit illégal que votre Pirate ait une quantité négative d'or.

public Pirate(String name, int initialGold) {
    if(initialGold < 0)
        throw new IllegalArgumentException("Init Gold must be >= 0");

Ensuite, dans votre scénario de test JUnit, attendez le IllegalArgumentException.

@Test(expected=IllegalArgumentException.class)
public static void exceptionTest() {
7
rgettman