Dans JUnit4, vous pouvez écrire des tests unitaires paramétrés en fournissant une collection de paramètres dans une méthode, qui sera transmise au constructeur du test et testée dans une autre méthode. Si j'ai un paramètre pour lequel je m'attends à ce qu'une exception soit levée, comment puis-je le spécifier?Comment tester des exceptions dans un test paramétré?
Répondre
if (parameter == EXCEPTION_EXPECTED) {
try {
method(parameter);
fail("didn't throw an exception!");
} catch (ExpectedException ee) {
// Test succeded!
}
}
Si vous avez utilisé catch-exception au lieu des annotations et des règles correspondantes de junit4, alors votre code ressemblerait à ceci:
catchException(obj).method(parameter);
if (parameter != EXCEPTION_EXPECTED) {
assert caughtException() instanceof ExpectedException;
}
// more assertions
Contrairement à ce que d'autres suggèrent, je ne présenterait aucune sorte de logique aux tests - même si simple!
Ce que vous devriez avoir sont deux méthodes d'essai:
- premier prend des paramètres valides (et attend une sortie)
- secondes prend des paramètres non valides (et attend des exceptions)
Je ne sais pas si JUnit avec ses tests paramétrés basés sur le constructeur est capable de le faire. Probablement, vous devrez créer deux classes de test pour cela. Aller avec JUnit Params ou TestNG qui offrent une solution beaucoup plus pratique.
Gabriel, regardez la règle TestWatcher (depuis JUnit 4.9). Voici l'exemple de code cité http://junit-team.github.io/junit/javadoc/4.11/org/junit/rules/TestWatcher.html:
public static class WatchmanTest {
private static String watchedLog;
@Rule
public TestWatcher watchman= new TestWatcher() {
@Override
protected void failed(Throwable e, Description description) {
watchedLog+= description + "\n";
}
@Override
protected void succeeded(Description description) {
watchedLog+= description + " " + "success!\n";
}
};
@Test
public void fails() {
fail();
}
@Test
public void succeeds() {
}
}
Une autre approche serait d'utiliser ErrorCollector de JUnit 4.7: @Rule ExpectedException publique jeté = ExpectedException.none();
@Test
public void testCollectingErrors() {
thrown.handleAssertionErrors();
thrown.expect(MultipleFailureException.class); // or #expectMessage()/#expectCause()
collector.checkThat("a", equalTo("b"));
//...
}
c'est comment j'utiliser le test JUnit paramétrés avec des exceptions prévues:
@RunWith(Parameterized.class)
public class CalcDivTest {
@Parameter(0)
public int num1;
@Parameter(1)
public int num2;
@Parameter(2)
public int expectedResult;
@Parameter(3)
public Class<? extends Exception> expectedException;
@Parameter(4)
public String expectedExceptionMsg;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
// calculation scenarios:
{ 120, 10, 12, null, null }, // simple div
{ 120, 0, -1, ArithmeticException.class, "/ by zero" }, // div by zero
});
}
@Test
public void testDiv() throws CCalculationException {
//setup expected exception
if (expectedException != null) {
thrown.expect(expectedException);
thrown.expectMessage(expectedExceptionMsg);
}
assertEquals("calculation result is not as", expectedResult, div(num1, num2));
}
private int div(int a, int b) {
return a/b;
}
}
J'espériez une solution plus raisonnable - par exemple quelque chose comme plusieurs méthodes @Parameters avec l'argument d'annotation attendu facultatif, mais je suppose que quelque chose comme ça ne fait pas partie du framework. Merci quand même. –