Quelle est l'utilisation réelle de «échec» dans le cas de test JUnit?


Réponses:


138

Quelques cas où je l'ai trouvé utile:

  • marquer un test incomplet, il échoue et vous avertit jusqu'à ce que vous puissiez le terminer
  • s'assurer qu'une exception est levée:
try{
  // do stuff...
  fail("Exception not thrown");
}catch(Exception e){
  assertTrue(e.hasSomeFlag());
}

Remarque:

Depuis JUnit4, il existe un moyen plus élégant de tester qu'une exception est levée: utilisez l'annotation @Test(expected=IndexOutOfBoundsException.class)

Cependant, cela ne fonctionnera pas si vous souhaitez également inspecter l'exception, vous en avez toujours besoin fail().


5
Considérez ce billet de blog sur les mérites relatifs de l'annotation d'échec par rapport à l'annotation attendue: blog.jooq.org/2016/01/20/…
lbalazscs

4
@sleske "si vous souhaitez également inspecter l'exception, vous avez toujours besoin de fail ()" - non. ExpectedException est le chemin, voir github.com/junit-team/junit4/wiki/exception-testing
kraxor

@kraxor: C'est vrai, je ne le savais pas quand j'ai écrit la réponse (ce n'était probablement même pas là à l'époque).
sleske

14

disons que vous écrivez un cas de test pour un flux -ve où le code testé doit déclencher une exception

try{
   bizMethod(badData);
   fail(); // FAIL when no exception is thrown
} catch (BizException e) {
   assert(e.errorCode == THE_ERROR_CODE_U_R_LOOKING_FOR)
}

10

Je pense que le cas d'utilisation habituel est de l'appeler lorsqu'aucune exception n'a été lancée dans un test négatif.

Quelque chose comme le pseudo-code suivant:

test_addNilThrowsNullPointerException()
{
    try {
        foo.add(NIL);                      // we expect a NullPointerException here
        fail("No NullPointerException");   // cause the test to fail if we reach this            
     } catch (NullNullPointerException e) {
        // OK got the expected exception
    }
}

3
Si vous ne cochez pas quelque chose dans le bloc catch, vous pouvez utiliser l'annotation de méthode @ExpectedException (NullNullPointerException.class) pour déclarer que vous attendez une exception (d'un type spécial).
FrVaBe

8

Je l'ai utilisé dans le cas où quelque chose aurait mal tourné dans ma méthode @Before.

public Object obj;

@Before
public void setUp() {
    // Do some set up
    obj = new Object();
}

@Test
public void testObjectManipulation() {
    if(obj == null) {
        fail("obj should not be null");
     }

    // Do some other valuable testing
}

1
Oui, les conditions préalables de test sont bonnes. Cependant, si vous voulez vous assurer que la @Beforeméthode a réussi, il est probablement préférable de la vérifier directement dans cette méthode. En prime, au moins JUnit et TestNG rapporteront même un échec différent pour les erreurs de @Before/ @Aftermethods, donc peuvent voir que le problème n'était pas dans le test lui-même.
sleske

4

C'est ainsi que j'utilise la méthode Fail.

Votre scénario de test peut se terminer dans trois états

  1. Réussi: la fonction testée s'est exécutée avec succès et a renvoyé les données comme prévu
  2. Non réussi: la fonction testée a été exécutée avec succès mais les données renvoyées n'étaient pas comme prévu
  3. Échec: la fonction ne s'est pas exécutée correctement et cela n'a pas été

prévu (contrairement aux cas de test négatifs qui s'attendent à ce qu'une exception se produise).

Si vous utilisez Eclipse, trois états sont indiqués respectivement par un marqueur vert, bleu et rouge.

J'utilise l'opération d'échec pour le troisième scénario.

par exemple: public Integer add (integer a, Integer b) {return new Integer (a.intValue () + b.intValue ())}

  1. Cas passé: a = new Interger (1), b = new Integer (2) et la fonction a renvoyé 3
  2. Cas non passé: a = new Interger (1), b = new Integer (2) et la fonction a renvoyé une valeur soem différente de 3
  3. Cas d'échec: a = null, b = null et la fonction lève une NullPointerException

1
Si vous regardez le code source de JUnit, vous verrez que les assertions utilisent fail().
Daniel C.Sobral

3

Moi, par exemple, j'utilise fail()pour indiquer des tests qui ne sont pas encore terminés (ça arrive); sinon, ils se montreraient réussis.

Cela est peut-être dû au fait que je ne suis pas au courant d'une sorte de fonctionnalité incomplète (), qui existe dans NUnit.


2

Dans les paramètres simultanés et / ou asynchrones, vous voudrez peut-être vérifier que certaines méthodes (par exemple, les délégués, les écouteurs d'événements, les gestionnaires de réponses, vous le nommez) ne sont pas appelées. Mis à part les frameworks moqueurs, vous pouvez appeler fail()ces méthodes pour échouer les tests. Les délais d'expiration sont une autre condition de défaillance naturelle dans de tels scénarios.

Par exemple:

final CountDownLatch latch = new CountDownLatch(1);

service.asyncCall(someParameter, new ResponseHandler<SomeType>() {
    @Override
    public void onSuccess(SomeType result) {
        assertNotNull(result);
        // Further test assertions on the result
        latch.countDown();
    }

    @Override
    public void onError(Exception e) {
        fail(exception.getMessage());
        latch.countDown();
    }
});

if ( !latch.await(5, TimeUnit.SECONDS) ) {
    fail("No response after 5s");
}

0

Le cas d'utilisation le plus important est probablement la vérification des exceptions.

Alors que junit4 inclut l' élément attendu pour vérifier si une exception s'est produite, il semble qu'il ne fasse pas partie du nouveau junit5. Un autre avantage de l'utilisation par fail()rapport au expectedest que vous pouvez le combiner avec le finallynettoyage des cas de test.

dao.insert(obj);
try {
  dao.insert(obj);
  fail("No DuplicateKeyException thrown.");
} catch (DuplicateKeyException e) {
  assertEquals("Error code doesn't match", 123, e.getErrorCode());
} finally {
  //cleanup
  dao.delete(obj);
}

Comme indiqué dans un autre commentaire. Avoir un test qui échoue jusqu'à ce que vous puissiez terminer sa mise en œuvre semble également raisonnable.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.