/* * 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.migrationsupport.rules; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static org.junit.platform.commons.meta.API.Usage.Experimental; import java.util.function.Function; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.ExtensionContext.Namespace; import org.junit.jupiter.api.extension.ExtensionContext.Store; import org.junit.jupiter.api.extension.TestExecutionExceptionHandler; import org.junit.jupiter.api.extension.TestExtensionContext; import org.junit.jupiter.migrationsupport.rules.adapter.AbstractTestRuleAdapter; import org.junit.jupiter.migrationsupport.rules.adapter.ExpectedExceptionAdapter; import org.junit.jupiter.migrationsupport.rules.member.TestRuleAnnotatedMember; import org.junit.platform.commons.meta.API; import org.junit.rules.ExpectedException; /** * This {@code Extension} provides native support for the * {@link ExpectedException} rule from JUnit 4. * * <p>By using this class-level extension on a test class, * {@code ExpectedException} can continue to be used. * * <p>However, you should rather switch to * {@link org.junit.jupiter.api.Assertions#assertThrows} for new code. * * @since 5.0 * @see org.junit.jupiter.api.Assertions#assertThrows * @see org.junit.rules.ExpectedException * @see org.junit.rules.TestRule * @see org.junit.Rule */ @API(Experimental) public class ExpectedExceptionSupport implements AfterEachCallback, TestExecutionExceptionHandler { private static final String EXCEPTION_WAS_HANDLED = "exceptionWasHandled"; private final Function<TestRuleAnnotatedMember, AbstractTestRuleAdapter> adapterGenerator = ExpectedExceptionAdapter::new; private final TestRuleFieldSupport fieldSupport = new TestRuleFieldSupport(this.adapterGenerator, ExpectedException.class); private final TestRuleMethodSupport methodSupport = new TestRuleMethodSupport(this.adapterGenerator, ExpectedException.class); @Override public void handleTestExecutionException(TestExtensionContext context, Throwable throwable) throws Throwable { getStore(context).put(EXCEPTION_WAS_HANDLED, TRUE); this.methodSupport.handleTestExecutionException(context, throwable); this.fieldSupport.handleTestExecutionException(context, throwable); } @Override public void afterEach(TestExtensionContext context) throws Exception { boolean exceptionWasHandled = getStore(context).getOrComputeIfAbsent(EXCEPTION_WAS_HANDLED, key -> FALSE, Boolean.class); if (!exceptionWasHandled) { this.methodSupport.afterEach(context); this.fieldSupport.afterEach(context); } } private Store getStore(TestExtensionContext context) { return context.getStore(Namespace.create(ExpectedExceptionSupport.class, context.getUniqueId())); } }