Qual è l'effettivo utilizzo di "fail" nel test case di JUnit?


Risposte:


138

Alcuni casi in cui l'ho trovato utile:

  • contrassegna un test incompleto, in modo che fallisca e ti avverta finché non lo finisci
  • assicurandosi che venga generata un'eccezione:
try{
  // do stuff...
  fail("Exception not thrown");
}catch(Exception e){
  assertTrue(e.hasSomeFlag());
}

Nota:

A partire da JUnit4, esiste un modo più elegante per verificare che venga generata un'eccezione: utilizzare l'annotazione @Test(expected=IndexOutOfBoundsException.class)

Tuttavia, questo non funzionerà se vuoi anche ispezionare l'eccezione, quindi hai ancora bisogno fail().


5
Considera questo post del blog sui meriti relativi dell'annotazione fallita e attesa: blog.jooq.org/2016/01/20/…
lbalazscs

4
@sleske "se vuoi anche controllare l'eccezione, allora hai ancora bisogno di fail ()" - no. ExpectedException è il modo, vedi github.com/junit-team/junit4/wiki/exception-testing
kraxor

@kraxor: Vero, non lo sapevo quando ho scritto la risposta (probabilmente non era nemmeno in giro allora).
sleske

14

diciamo che stai scrivendo un test case per un flusso -ve in cui il codice da testare dovrebbe sollevare un'eccezione

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

10

Penso che il solito caso d'uso sia chiamarlo quando nessuna eccezione è stata lanciata in un test negativo.

Qualcosa di simile al seguente pseudo-codice:

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
Se non controlli qualcosa nel blocco catch, puoi utilizzare l'annotazione del metodo @ExpectedException (NullNullPointerException.class) per dichiarare che ti aspetti un'eccezione (di un tipo speciale).
FrVaBe

8

L'ho usato nel caso in cui qualcosa potrebbe essere andato storto nel mio metodo @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
Sì, le condizioni preliminari del test sono buone. Tuttavia, se vuoi assicurarti che il @Beforemetodo abbia avuto successo, probabilmente è meglio controllarlo direttamente in quel metodo. Come bonus, almeno JUnit e TestNG segnaleranno anche un errore diverso per errori da @Before/ @Aftermethods, quindi puoi vedere che il problema non era nel test stesso.
sleske

4

È così che utilizzo il metodo Fail.

Ci sono tre stati in cui può finire il tuo caso di test

  1. Superato: la funzione sotto test è stata eseguita correttamente e ha restituito i dati come previsto
  2. Non superato: la funzione sottoposta a test è stata eseguita correttamente ma i dati restituiti non erano come previsto
  3. Non riuscito: la funzione non è stata eseguita correttamente e questo non lo è stato

previsto (a differenza dei casi di test negativi che prevedono il verificarsi di un'eccezione).

Se stai usando eclipse, tre stati sono indicati rispettivamente da un indicatore verde, blu e rosso.

Uso l'operazione di errore per il terzo scenario.

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

  1. Caso superato: a = new Interger (1), b = new Integer (2) e la funzione ha restituito 3
  2. Caso non superato: a = new Interger (1), b = new Integer (2) e la funzione ha restituito un valore diverso da 3
  3. Caso non riuscito: a = null, b = null e la funzione genera un'eccezione NullPointerException

1
Se guardi il codice sorgente di JUnit, vedrai che le asserzioni usano fail().
Daniel C. Sobral

3

Io, ad esempio, uso fail()per indicare test che non sono ancora finiti (succede); in caso contrario, si dimostrerebbero di successo.

Ciò è forse dovuto al fatto che non sono a conoscenza di una sorta di funzionalità incompleta (), che esiste in NUnit.


2

Nelle impostazioni simultanee e / o asincrone, potresti voler verificare che alcuni metodi (ad es. Delegati, ascoltatori di eventi, gestori di risposte e così via) non vengano chiamati. Mocking frameworks a parte, puoi chiamarefail() questi metodi per fallire i test. I timeout scaduti sono un'altra condizione di errore naturale in tali scenari.

Per esempio:

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

Il caso d'uso più importante è probabilmente il controllo delle eccezioni.

Sebbene junit4 includa l' elemento previsto per verificare se si è verificata un'eccezione, sembra che non faccia parte del nuovo junit5. Un altro vantaggio dell'utilizzo di fail()over the expectedè che puoi combinarlo finallyconsentendo la pulizia del caso di 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);
}

Come notato in un altro commento. Anche il fatto che un test fallisca finché non si riesce a completare l'implementazione sembra ragionevole.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.