diff --git a/build.gradle b/build.gradle index a4a75ab9c07..7699be6cf85 100644 --- a/build.gradle +++ b/build.gradle @@ -73,9 +73,9 @@ configure(allprojects) { project -> ext.jspVersion = "2.3.2-b02" ext.jtaVersion = "1.2" ext.junitVersion = "4.12" - ext.junitVintageVersion = "4.12.0-M4" - ext.junitJupiterVersion = '5.0.0-M4' - ext.junitPlatformVersion = '1.0.0-M4' + ext.junitVintageVersion = "4.12.0-M5" + ext.junitJupiterVersion = '5.0.0-M5' + ext.junitPlatformVersion = '1.0.0-M5' ext.log4jVersion = '2.8.2' ext.nettyVersion = "4.1.12.Final" ext.niomultipartVersion = "1.1.0" diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java index d24caccb0ac..cc8276d2a35 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java @@ -23,10 +23,10 @@ import java.util.function.Function; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.junit.jupiter.api.extension.ConditionEvaluationResult; -import org.junit.jupiter.api.extension.ContainerExecutionCondition; +import org.junit.jupiter.api.extension.ExecutionCondition; import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.TestExecutionCondition; import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionResolver; @@ -39,9 +39,9 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * Abstract base class for implementations of {@link ContainerExecutionCondition} - * and {@link TestExecutionCondition} that evaluate expressions configured via - * annotations to determine if a container or test is enabled. + * Abstract base class for implementations of {@link ExecutionCondition} that + * evaluate expressions configured via annotations to determine if a container + * or test is enabled. * *
Expressions can be any of the following. * @@ -61,7 +61,7 @@ import org.springframework.util.StringUtils; * @see EnabledIf * @see DisabledIf */ -abstract class AbstractExpressionEvaluatingCondition implements ContainerExecutionCondition, TestExecutionCondition { +abstract class AbstractExpressionEvaluatingCondition implements ExecutionCondition { private static final Log logger = LogFactory.getLog(AbstractExpressionEvaluatingCondition.class); diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIfCondition.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIfCondition.java index 1b9392a398e..883af7902cc 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIfCondition.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIfCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,24 +17,18 @@ package org.springframework.test.context.junit.jupiter; import org.junit.jupiter.api.extension.ConditionEvaluationResult; -import org.junit.jupiter.api.extension.ContainerExecutionCondition; -import org.junit.jupiter.api.extension.ContainerExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.TestExecutionCondition; -import org.junit.jupiter.api.extension.TestExtensionContext; /** - * {@code DisabledIfCondition} is a composite {@link ContainerExecutionCondition} - * and {@link TestExecutionCondition} that supports the {@link DisabledIf @DisabledIf} - * annotation when using the Spring TestContext Framework in conjunction - * with JUnit 5's Jupiter programming model. + * {@code DisabledIfCondition} is an {@link ExecutionCondition} that supports the + * {@link DisabledIf @DisabledIf} annotation when using the Spring TestContext + * Framework in conjunction with JUnit 5's Jupiter programming model. * *
Any attempt to use the {@code DisabledIfCondition} without the presence of * {@link DisabledIf @DisabledIf} will result in an enabled * {@link ConditionEvaluationResult}. * * @author Sam Brannen - * @author Tadaya Tsuyukubo * @since 5.0 * @see DisabledIf * @see EnabledIf @@ -43,26 +37,14 @@ import org.junit.jupiter.api.extension.TestExtensionContext; public class DisabledIfCondition extends AbstractExpressionEvaluatingCondition { /** - * Containers are disabled if {@code @DisabledIf} is present on the test class - * and the configured expression evaluates to {@code true}. + * Containers and tests are disabled if {@code @DisabledIf} is present on the + * corresponding test class or test method and the configured expression evaluates + * to {@code true}. */ @Override - public ConditionEvaluationResult evaluate(ContainerExtensionContext context) { - return evaluateDisabledIf(context); - } - - /** - * Tests are disabled if {@code @DisabledIf} is present on the test method - * and the configured expression evaluates to {@code true}. - */ - @Override - public ConditionEvaluationResult evaluate(TestExtensionContext context) { - return evaluateDisabledIf(context); - } - - private ConditionEvaluationResult evaluateDisabledIf(ExtensionContext context) { - return evaluateAnnotation(DisabledIf.class, DisabledIf::expression, DisabledIf::reason, - DisabledIf::loadContext, false, context); + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + return evaluateAnnotation(DisabledIf.class, DisabledIf::expression, DisabledIf::reason, DisabledIf::loadContext, + false, context); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/EnabledIfCondition.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/EnabledIfCondition.java index b9eb00c48e5..edbc6887149 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/EnabledIfCondition.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/EnabledIfCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,12 @@ package org.springframework.test.context.junit.jupiter; import org.junit.jupiter.api.extension.ConditionEvaluationResult; -import org.junit.jupiter.api.extension.ContainerExecutionCondition; -import org.junit.jupiter.api.extension.ContainerExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.TestExecutionCondition; -import org.junit.jupiter.api.extension.TestExtensionContext; /** - * {@code EnabledIfCondition} is a composite {@link ContainerExecutionCondition} - * and {@link TestExecutionCondition} that supports the {@link EnabledIf @EnabledIf} - * annotation when using the Spring TestContext Framework in conjunction - * with JUnit 5's Jupiter programming model. + * {@code EnabledIfCondition} is an {@link ExecutionCondition} that supports the + * {@link EnabledIf @EnabledIf} annotation when using the Spring TestContext + * Framework in conjunction with JUnit 5's Jupiter programming model. * *
Any attempt to use the {@code EnabledIfCondition} without the presence of * {@link EnabledIf @EnabledIf} will result in an enabled @@ -42,26 +37,14 @@ import org.junit.jupiter.api.extension.TestExtensionContext; public class EnabledIfCondition extends AbstractExpressionEvaluatingCondition { /** - * Containers are enabled if {@code @EnabledIf} is present on the test class - * and the configured expression evaluates to {@code true}. + * Containers and tests are enabled if {@code @EnabledIf} is present on the + * corresponding test class or test method and the configured expression + * evaluates to {@code true}. */ @Override - public ConditionEvaluationResult evaluate(ContainerExtensionContext context) { - return evaluateEnabledIf(context); - } - - /** - * Tests are enabled if {@code @EnabledIf} is present on the test method - * and the configured expression evaluates to {@code true}. - */ - @Override - public ConditionEvaluationResult evaluate(TestExtensionContext context) { - return evaluateEnabledIf(context); - } - - private ConditionEvaluationResult evaluateEnabledIf(ExtensionContext context) { - return evaluateAnnotation(EnabledIf.class, EnabledIf::expression, EnabledIf::reason, - EnabledIf::loadContext, true, context); + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + return evaluateAnnotation(EnabledIf.class, EnabledIf::expression, EnabledIf::reason, EnabledIf::loadContext, + true, context); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java index 3f4dd77dfa4..1af93a39c5e 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java @@ -27,13 +27,11 @@ import org.junit.jupiter.api.extension.AfterTestExecutionCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; -import org.junit.jupiter.api.extension.ContainerExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext.Namespace; import org.junit.jupiter.api.extension.ExtensionContext.Store; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolver; -import org.junit.jupiter.api.extension.TestExtensionContext; import org.junit.jupiter.api.extension.TestInstancePostProcessor; import org.springframework.beans.factory.annotation.Autowired; @@ -52,6 +50,7 @@ import org.springframework.util.Assert; * * @author Sam Brannen * @since 5.0 + * @see org.springframework.test.context.junit.jupiter.EnabledIf * @see org.springframework.test.context.junit.jupiter.DisabledIf * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @@ -72,7 +71,7 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Delegates to {@link TestContextManager#beforeTestClass}. */ @Override - public void beforeAll(ContainerExtensionContext context) throws Exception { + public void beforeAll(ExtensionContext context) throws Exception { getTestContextManager(context).beforeTestClass(); } @@ -80,12 +79,12 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Delegates to {@link TestContextManager#afterTestClass}. */ @Override - public void afterAll(ContainerExtensionContext context) throws Exception { + public void afterAll(ExtensionContext context) throws Exception { try { getTestContextManager(context).afterTestClass(); } finally { - context.getStore(NAMESPACE).remove(context.getTestClass().get()); + context.getStore(NAMESPACE).remove(getRequiredTestClass(context)); } } @@ -101,9 +100,9 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Delegates to {@link TestContextManager#beforeTestMethod}. */ @Override - public void beforeEach(TestExtensionContext context) throws Exception { - Object testInstance = context.getTestInstance(); - Method testMethod = context.getTestMethod().get(); + public void beforeEach(ExtensionContext context) throws Exception { + Object testInstance = getRequiredTestInstance(context); + Method testMethod = getRequiredTestMethod(context); getTestContextManager(context).beforeTestMethod(testInstance, testMethod); } @@ -111,9 +110,9 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Delegates to {@link TestContextManager#beforeTestExecution}. */ @Override - public void beforeTestExecution(TestExtensionContext context) throws Exception { - Object testInstance = context.getTestInstance(); - Method testMethod = context.getTestMethod().get(); + public void beforeTestExecution(ExtensionContext context) throws Exception { + Object testInstance = getRequiredTestInstance(context); + Method testMethod = getRequiredTestMethod(context); getTestContextManager(context).beforeTestExecution(testInstance, testMethod); } @@ -121,10 +120,10 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Delegates to {@link TestContextManager#afterTestExecution}. */ @Override - public void afterTestExecution(TestExtensionContext context) throws Exception { - Object testInstance = context.getTestInstance(); - Method testMethod = context.getTestMethod().get(); - Throwable testException = context.getTestException().orElse(null); + public void afterTestExecution(ExtensionContext context) throws Exception { + Object testInstance = getRequiredTestInstance(context); + Method testMethod = getRequiredTestMethod(context); + Throwable testException = context.getExecutionException().orElse(null); getTestContextManager(context).afterTestExecution(testInstance, testMethod, testException); } @@ -132,10 +131,10 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Delegates to {@link TestContextManager#afterTestMethod}. */ @Override - public void afterEach(TestExtensionContext context) throws Exception { - Object testInstance = context.getTestInstance(); - Method testMethod = context.getTestMethod().get(); - Throwable testException = context.getTestException().orElse(null); + public void afterEach(ExtensionContext context) throws Exception { + Object testInstance = getRequiredTestInstance(context); + Method testMethod = getRequiredTestMethod(context); + Throwable testException = context.getExecutionException().orElse(null); getTestContextManager(context).afterTestMethod(testInstance, testMethod, testException); } @@ -149,11 +148,11 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * that is annotated with {@code @Autowired}, Spring will assume the responsibility * for resolving all parameters in the constructor. Consequently, no other registered * {@link ParameterResolver} will be able to resolve parameters. - * @see #resolve + * @see #resolveParameter * @see ParameterAutowireUtils#isAutowirable */ @Override - public boolean supports(ParameterContext parameterContext, ExtensionContext extensionContext) { + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { Parameter parameter = parameterContext.getParameter(); Executable executable = parameter.getDeclaringExecutable(); return (executable instanceof Constructor && @@ -165,14 +164,14 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * Resolve a value for the {@link Parameter} in the supplied {@link ParameterContext} by * retrieving the corresponding dependency from the test's {@link ApplicationContext}. *
Delegates to {@link ParameterAutowireUtils#resolveDependency}. - * @see #supports + * @see #supportsParameter * @see ParameterAutowireUtils#resolveDependency */ @Override @Nullable - public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) { + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { Parameter parameter = parameterContext.getParameter(); - Class> testClass = extensionContext.getTestClass().get(); + Class> testClass = getRequiredTestClass(extensionContext); ApplicationContext applicationContext = getApplicationContext(extensionContext); return ParameterAutowireUtils.resolveDependency(parameter, testClass, applicationContext); } @@ -195,9 +194,45 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes */ private static TestContextManager getTestContextManager(ExtensionContext context) { Assert.notNull(context, "ExtensionContext must not be null"); - Class> testClass = context.getTestClass().get(); + Class> testClass = getRequiredTestClass(context); Store store = context.getStore(NAMESPACE); return store.getOrComputeIfAbsent(testClass, TestContextManager::new, TestContextManager.class); } + /** + * Get the test class associated with the supplied {@code ExtensionContext}. + * @return the test class + * @throws IllegalStateException if the extension context does not contain + * a test class + */ + private static Class> getRequiredTestClass(ExtensionContext context) throws IllegalStateException { + Assert.notNull(context, "ExtensionContext must not be null"); + return context.getTestClass().orElseThrow( + () -> new IllegalStateException("JUnit failed to supply the test class in the ExtensionContext")); + } + + /** + * Get the test instance associated with the supplied {@code ExtensionContext}. + * @return the test instance + * @throws IllegalStateException if the extension context does not contain + * a test instance + */ + private static Object getRequiredTestInstance(ExtensionContext context) throws IllegalStateException { + Assert.notNull(context, "ExtensionContext must not be null"); + return context.getTestInstance().orElseThrow( + () -> new IllegalStateException("JUnit failed to supply the test instance in the ExtensionContext")); + } + + /** + * Get the test method associated with the supplied {@code ExtensionContext}. + * @return the test method + * @throws IllegalStateException if the extension context does not contain + * a test method + */ + private static Method getRequiredTestMethod(ExtensionContext context) throws IllegalStateException { + Assert.notNull(context, "ExtensionContext must not be null"); + return context.getTestMethod().orElseThrow( + () -> new IllegalStateException("JUnit failed to supply the test method in the ExtensionContext")); + } + } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/DisabledIfConditionTestCase.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/DisabledIfConditionTestCase.java index 03cda1cbd6c..ec7471d2e09 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/DisabledIfConditionTestCase.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/DisabledIfConditionTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,11 @@ import java.lang.reflect.Method; import java.util.Optional; import org.hamcrest.Matcher; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext.Store; -import org.junit.jupiter.api.extension.TestExtensionContext; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.TestContextManager; @@ -52,7 +53,7 @@ class DisabledIfConditionTestCase { @Test void missingDisabledIf() { - assertResult(condition.evaluate(buildExtensionContext("missingDisabledIf")), false, + assertResult(condition.evaluateExecutionCondition(buildExtensionContext("missingDisabledIf")), false, endsWith("missingDisabledIf() is enabled since @DisabledIf is not present")); } @@ -70,7 +71,7 @@ class DisabledIfConditionTestCase { void invalidExpressionEvaluationType() { String methodName = "nonBooleanOrStringExpression"; IllegalStateException exception = assertThrows(IllegalStateException.class, - () -> condition.evaluate(buildExtensionContext(methodName))); + () -> condition.evaluateExecutionCondition(buildExtensionContext(methodName))); Method method = ReflectionUtils.findMethod(getClass(), methodName); @@ -82,7 +83,7 @@ class DisabledIfConditionTestCase { void unsupportedStringEvaluationValue() { String methodName = "stringExpressionThatIsNeitherTrueNorFalse"; IllegalStateException exception = assertThrows(IllegalStateException.class, - () -> condition.evaluate(buildExtensionContext(methodName))); + () -> condition.evaluateExecutionCondition(buildExtensionContext(methodName))); Method method = ReflectionUtils.findMethod(getClass(), methodName); @@ -92,30 +93,30 @@ class DisabledIfConditionTestCase { @Test void disabledWithCustomReason() { - assertResult(condition.evaluate(buildExtensionContext("customReason")), true, is(equalTo("Because... 42!"))); + assertResult(condition.evaluateExecutionCondition(buildExtensionContext("customReason")), true, is(equalTo("Because... 42!"))); } @Test void disabledWithDefaultReason() { - assertResult(condition.evaluate(buildExtensionContext("defaultReason")), true, + assertResult(condition.evaluateExecutionCondition(buildExtensionContext("defaultReason")), true, endsWith("defaultReason() is disabled because @DisabledIf(\"#{1 + 1 eq 2}\") evaluated to true")); } @Test void notDisabledWithDefaultReason() { - assertResult(condition.evaluate(buildExtensionContext("neverDisabledWithDefaultReason")), false, endsWith( + assertResult(condition.evaluateExecutionCondition(buildExtensionContext("neverDisabledWithDefaultReason")), false, endsWith( "neverDisabledWithDefaultReason() is enabled because @DisabledIf(\"false\") did not evaluate to true")); } // ------------------------------------------------------------------------- - private TestExtensionContext buildExtensionContext(String methodName) { + private ExtensionContext buildExtensionContext(String methodName) { Class> testClass = SpringTestCase.class; Method method = ReflectionUtils.findMethod(getClass(), methodName); Store store = mock(Store.class); when(store.getOrComputeIfAbsent(any(), any(), any())).thenReturn(new TestContextManager(testClass)); - TestExtensionContext extensionContext = mock(TestExtensionContext.class); + ExtensionContext extensionContext = mock(ExtensionContext.class); when(extensionContext.getTestClass()).thenReturn(Optional.of(testClass)); when(extensionContext.getElement()).thenReturn(Optional.of(method)); when(extensionContext.getStore(any())).thenReturn(store); @@ -124,7 +125,7 @@ class DisabledIfConditionTestCase { private void assertExpressionIsBlank(String methodName) { IllegalStateException exception = assertThrows(IllegalStateException.class, - () -> condition.evaluate(buildExtensionContext(methodName))); + () -> condition.evaluateExecutionCondition(buildExtensionContext(methodName))); assertThat(exception.getMessage(), containsString("must not be blank")); }