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.
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
.
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.
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.
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() {