/*
* Copyright 2015-2017 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.junit.jupiter.engine;
import static org.assertj.core.api.Assertions.allOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.assertRecordedExecutionEventsContainsExactly;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.container;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.engine;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.event;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.finishedSuccessfully;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.finishedWithFailure;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.started;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.test;
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.isA;
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.message;
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.suppressed;
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Optional;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.platform.engine.test.event.ExecutionEventRecorder;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.opentest4j.AssertionFailedError;
/**
* Integration tests that verify correct exception handling in the {@link JupiterTestEngine}.
*
* @since 5.0
*/
class ExceptionHandlingTests extends AbstractJupiterTestEngineTests {
@Test
void failureInTestMethodIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("failingTest");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
ExecutionEventRecorder eventRecorder = executeTests(request);
assertEquals(1, eventRecorder.getTestStartedCount(), "# tests started");
assertEquals(1, eventRecorder.getTestFailedCount(), "# tests failed");
assertRecordedExecutionEventsContainsExactly(eventRecorder.getFailedTestFinishedEvents(), //
event(test("failingTest"),
finishedWithFailure(allOf(isA(AssertionFailedError.class), message("always fails")))));
}
@Test
void uncheckedExceptionInTestMethodIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("testWithUncheckedException");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
ExecutionEventRecorder eventRecorder = executeTests(request);
assertEquals(1, eventRecorder.getTestStartedCount(), "# tests started");
assertEquals(1, eventRecorder.getTestFailedCount(), "# tests failed");
assertRecordedExecutionEventsContainsExactly(eventRecorder.getFailedTestFinishedEvents(), //
event(test("testWithUncheckedException"),
finishedWithFailure(allOf(isA(RuntimeException.class), message("unchecked")))));
}
@Test
void checkedExceptionInTestMethodIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("testWithCheckedException");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
ExecutionEventRecorder eventRecorder = executeTests(request);
assertEquals(1, eventRecorder.getTestStartedCount(), "# tests started");
assertEquals(1, eventRecorder.getTestFailedCount(), "# tests failed");
assertRecordedExecutionEventsContainsExactly(eventRecorder.getFailedTestFinishedEvents(), //
event(test("testWithCheckedException"),
finishedWithFailure(allOf(isA(IOException.class), message("checked")))));
}
@Test
void checkedExceptionInBeforeEachIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("succeedingTest");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
FailureTestCase.exceptionToThrowInBeforeEach = Optional.of(new IOException("checked"));
ExecutionEventRecorder eventRecorder = executeTests(request);
assertEquals(1, eventRecorder.getTestStartedCount(), "# tests started");
assertEquals(1, eventRecorder.getTestFailedCount(), "# tests failed");
assertRecordedExecutionEventsContainsExactly(eventRecorder.getFailedTestFinishedEvents(),
event(test("succeedingTest"), finishedWithFailure(allOf(isA(IOException.class), message("checked")))));
}
@Test
void checkedExceptionInAfterEachIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("succeedingTest");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
FailureTestCase.exceptionToThrowInAfterEach = Optional.of(new IOException("checked"));
ExecutionEventRecorder eventRecorder = executeTests(request);
assertEquals(1, eventRecorder.getTestStartedCount(), "# tests started");
assertEquals(1, eventRecorder.getTestFailedCount(), "# tests failed");
assertRecordedExecutionEventsContainsExactly(eventRecorder.getFailedTestFinishedEvents(),
event(test("succeedingTest"), finishedWithFailure(allOf(isA(IOException.class), message("checked")))));
}
@Test
void checkedExceptionInAfterEachIsSuppressedByExceptionInTest() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("testWithUncheckedException");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
FailureTestCase.exceptionToThrowInAfterEach = Optional.of(new IOException("checked"));
ExecutionEventRecorder eventRecorder = executeTests(request);
assertRecordedExecutionEventsContainsExactly(eventRecorder.getExecutionEvents(), //
event(engine(), started()), //
event(container(FailureTestCase.class), started()), //
event(test("testWithUncheckedException"), started()), //
event(test("testWithUncheckedException"),
finishedWithFailure(allOf( //
isA(RuntimeException.class), //
message("unchecked"), //
suppressed(0, allOf(isA(IOException.class), message("checked")))))), //
event(container(FailureTestCase.class), finishedSuccessfully()), //
event(engine(), finishedSuccessfully()));
}
@Test
void checkedExceptionInBeforeAllIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("succeedingTest");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
FailureTestCase.exceptionToThrowInBeforeAll = Optional.of(new IOException("checked"));
ExecutionEventRecorder eventRecorder = executeTests(request);
assertRecordedExecutionEventsContainsExactly(eventRecorder.getExecutionEvents(), //
event(engine(), started()), //
event(container(FailureTestCase.class), started()), //
event(container(FailureTestCase.class),
finishedWithFailure(allOf(isA(IOException.class), message("checked")))), //
event(engine(), finishedSuccessfully()));
}
@Test
void checkedExceptionInAfterAllIsRegistered() throws NoSuchMethodException {
Method method = FailureTestCase.class.getDeclaredMethod("succeedingTest");
LauncherDiscoveryRequest request = request().selectors(selectMethod(FailureTestCase.class, method)).build();
FailureTestCase.exceptionToThrowInAfterAll = Optional.of(new IOException("checked"));
ExecutionEventRecorder eventRecorder = executeTests(request);
assertRecordedExecutionEventsContainsExactly(eventRecorder.getExecutionEvents(), //
event(engine(), started()), //
event(container(FailureTestCase.class), started()), //
event(test("succeedingTest"), started()), //
event(test("succeedingTest"), finishedSuccessfully()), //
event(container(FailureTestCase.class),
finishedWithFailure(allOf(isA(IOException.class), message("checked")))), //
event(engine(), finishedSuccessfully()));
}
@AfterEach
public void cleanUpExceptions() {
FailureTestCase.exceptionToThrowInBeforeAll = Optional.empty();
FailureTestCase.exceptionToThrowInAfterAll = Optional.empty();
FailureTestCase.exceptionToThrowInBeforeEach = Optional.empty();
FailureTestCase.exceptionToThrowInAfterEach = Optional.empty();
}
private static class FailureTestCase {
static Optional<Throwable> exceptionToThrowInBeforeAll = Optional.empty();
static Optional<Throwable> exceptionToThrowInAfterAll = Optional.empty();
static Optional<Throwable> exceptionToThrowInBeforeEach = Optional.empty();
static Optional<Throwable> exceptionToThrowInAfterEach = Optional.empty();
@BeforeAll
static void beforeAll() throws Throwable {
if (exceptionToThrowInBeforeAll.isPresent())
throw exceptionToThrowInBeforeAll.get();
}
@AfterAll
static void afterAll() throws Throwable {
if (exceptionToThrowInAfterAll.isPresent())
throw exceptionToThrowInAfterAll.get();
}
@BeforeEach
void beforeEach() throws Throwable {
if (exceptionToThrowInBeforeEach.isPresent())
throw exceptionToThrowInBeforeEach.get();
}
@AfterEach
void afterEach() throws Throwable {
if (exceptionToThrowInAfterEach.isPresent())
throw exceptionToThrowInAfterEach.get();
}
@Test
void succeedingTest() {
}
@Test
void failingTest() {
Assertions.fail("always fails");
}
@Test
void testWithUncheckedException() {
throw new RuntimeException("unchecked");
}
@Test
void testWithCheckedException() throws IOException {
throw new IOException("checked");
}
}
}