388 Stimmen

Wie kann ich meine Ausnahmemeldung mit der JUnit-Test-Annotation bestätigen?

Ich habe ein paar JUnit-Tests geschrieben mit @Test Bemerkung. Wenn meine Testmethode eine geprüfte Ausnahme auslöst und ich die Nachricht zusammen mit der Ausnahme bestätigen möchte, gibt es eine Möglichkeit, dies mit JUnit zu tun @Test Bemerkung? AFAIK, JUnit 4.7 bietet diese Funktion nicht, aber hat jede zukünftige Versionen bieten es? Ich weiß, dass man in .NET die Nachricht und die Ausnahmeklasse bestätigen kann. Ich suche nach einer ähnlichen Funktion in der Java-Welt.

Das ist es, was ich will:

@Test (expected = RuntimeException.class, message = "Employee ID is null")
public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() {}

582voto

Jesse Merriman Punkte 6129

Sie könnten die @Rule Vermerk mit ExpectedException etwa so:

@Rule
public ExpectedException expectedEx = ExpectedException.none();

@Test
public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() throws Exception {
    expectedEx.expect(RuntimeException.class);
    expectedEx.expectMessage("Employee ID is null");

    // do something that should throw the exception...
    System.out.println("=======Starting Exception process=======");
    throw new NullPointerException("Employee ID is null");
}

Beachten Sie, dass das Beispiel in der ExpectedException docs ist (derzeit) falsch - es gibt keinen öffentlichen Konstruktor, also müssen Sie ExpectedException.none() .

117voto

Johan Boberg Punkte 3111

In JUnit 4.13 können Sie das tun:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;

...

@Test
void exceptionTesting() {
  IllegalArgumentException exception = assertThrows(
    IllegalArgumentException.class, 
    () -> { throw new IllegalArgumentException("a message"); }
  );

  assertEquals("a message", exception.getMessage());
}

Dies funktioniert auch in JUnit 5 aber mit unterschiedlichen Importen:

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

...

65voto

Raystorm Punkte 5731

Ich mag die @Rule Antwort. Wenn Sie jedoch aus irgendeinem Grund keine Regeln verwenden möchten. Es gibt noch eine dritte Möglichkeit.

@Test (expected = RuntimeException.class)
public void myTestMethod()
{
   try
   {
      //Run exception throwing operation here
   }
   catch(RuntimeException re)
   {
      String message = "Employee ID is null";
      assertEquals(message, re.getMessage());
      throw re;
    }
    fail("Employee Id Null exception did not throw!");
  }

38voto

c_maker Punkte 17938

Müssen Sie die @Test(expected=SomeException.class) ? Wenn wir die tatsächliche Meldung der Ausnahme bestätigen müssen, tun wir Folgendes.

@Test
public void myTestMethod()
{
  try
  {
    final Integer employeeId = null;
    new Employee(employeeId);
    fail("Should have thrown SomeException but did not!");
  }
  catch( final SomeException e )
  {
    final String msg = "Employee ID is null";
    assertEquals(msg, e.getMessage());
  }
}

12voto

Krzysztof Cislo Punkte 361

Eigentlich ist die beste Verwendung mit try/catch. Warum? Weil Sie den Ort kontrollieren können, an dem Sie die Ausnahme erwarten.

Betrachten Sie dieses Beispiel:

@Test (expected = RuntimeException.class)
public void someTest() {
   // test preparation
   // actual test
}

Was ist, wenn eines Tages der Code geändert wird und die Testvorbereitung eine RuntimeException auslöst? In diesem Fall wird der eigentliche Test nicht einmal getestet, und selbst wenn er keine Ausnahme auslöst, wird der Test bestanden.

Deshalb ist es viel besser, try/catch zu verwenden, als sich auf die Annotation zu verlassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X