Qual é o uso real de 'fail' no caso de teste JUnit?

Respostas:

137

Alguns casos em que eu achei útil:

  • marque um teste incompleto, portanto ele falha e avisa você até que você possa concluí-lo
  • certificando-se de que uma exceção seja lançada:
try{
  // do stuff...
  fail("Exception not thrown");
}catch(Exception e){
  assertTrue(e.hasSomeFlag());
}

Nota:

Desde o JUnit4, existe uma maneira mais elegante de testar se uma exceção está sendo lançada: Use a anotação @Test(expected=IndexOutOfBoundsException.class)

No entanto, isso não funcionará se você também quiser inspecionar a exceção, e ainda precisará fail().

sleske
fonte
5
Considere esta publicação no blog sobre os méritos relativos da falha e da anotação esperada: blog.jooq.org/2016/01/20/…
lbalazscs
4
@sleske "se você também quiser inspecionar a exceção, ainda precisará de fail ()" - não. ExpectedException é o caminho, consulte github.com/junit-team/junit4/wiki/exception-testing
kraxor:
@kraxor: É verdade que eu não sabia disso quando escrevi a resposta (provavelmente ainda não era por aí).
sleske
14

digamos que você esteja escrevendo um caso de teste para um fluxo -ve em que o código que está sendo testado deve gerar uma exceção

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

Acho que o caso de uso usual é chamá-lo quando nenhuma exceção foi lançada em um teste negativo.

Algo como o seguinte pseudo-código:

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
    }
}
filante
fonte
3
Se você não verificar algo no bloco catch, poderá usar a anotação do método @ExpectedException (NullNullPointerException.class) para declarar que espera uma exceção (de um tipo especial).
FrVaBe
8

Eu usei no caso em que algo pode ter dado errado no meu método @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
}
Ryan D
fonte
1
Sim, testar pré-condições é bom. No entanto, se você quiser garantir que o @Beforemétodo seja bem-sucedido, provavelmente é melhor verificar diretamente nesse método. Como um bônus, pelo menos o JUnit e o TestNG relatam até uma falha diferente para erros de @Before/ @Aftermétodos, portanto, podemos ver que o problema não estava no próprio teste.
sleske
4

É assim que eu uso o método Fail.

Existem três estados em que seu caso de teste pode terminar em

  1. Aprovado: a função em teste foi executada com sucesso e retornou os dados conforme o esperado
  2. Não aprovado: a função em teste foi executada com sucesso, mas os dados retornados não foram os esperados
  3. Falha: A função não foi executada com êxito e isso não foi

pretendido (ao contrário dos casos de teste negativos que esperam que ocorra uma exceção).

Se você estiver usando o eclipse, três estados serão indicados por um marcador verde, azul e vermelho, respectivamente.

Eu uso a operação de falha no terceiro cenário.

por exemplo: público Número inteiro add (número inteiro a, Número inteiro b) {retorna novo Número inteiro (a.intValue () + b.intValue ())}

  1. Caso passado: a = novo Interger (1), b = novo Inteiro (2) e a função retornou 3
  2. Caso Não Passado: a = novo Interger (1), b = novo Inteiro (2) e a função retornou um valor diferente de 3
  3. Caso com falha: a = nulo, b = nulo e a função lança um NullPointerException
user3044364
fonte
1
Se você olhar para o código fonte do JUnit, verá que as afirmações são usadas fail().
Daniel C. Sobral
3

Eu, por exemplo, uso fail()para indicar testes que ainda não foram concluídos (isso acontece); caso contrário, eles apareceriam como bem-sucedidos.

Talvez isso se deva ao fato de eu não ter conhecimento de algum tipo de funcionalidade incompleta () que existe no NUnit.

Alen Siljak
fonte
2

Em configurações simultâneas e / ou assíncronas, convém verificar se determinados métodos (por exemplo, delegados, ouvintes de eventos, manipuladores de resposta, o nome dele) não são chamados. Zombando de estruturas de lado, você pode chamar fail()esses métodos para falhar nos testes. Os tempos limite expirados são outra condição de falha natural nesses cenários.

Por exemplo:

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");
}
Rafael
fonte
0

O caso de uso mais importante é provavelmente a verificação de exceções.

Embora junit4 inclua o elemento esperado para verificar se uma exceção ocorreu, parece que não faz parte do junit5 mais recente. Outra vantagem do uso fail()excessivo expectedé que você pode combiná-lo com a finallylimpeza de caso de teste.

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);
}

Como observado em outro comentário. Ter um teste com falha até que você possa concluir a implementação também parece razoável.

Udo Held
fonte