diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIf.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIf.java new file mode 100644 index 000000000000..eefbd43bfc06 --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/DisabledIf.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit.jupiter; + +import org.springframework.core.annotation.AliasFor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Disable JUnit 5(Jupiter) tests when evaluated condition returns "true" + * that can be either case insensitive {@code String} or {@code Boolean#TRUE}. + * + * @author Tadaya Tsuyukubo + * @since 5.0 + * @see SpringExtension + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DisabledIf { + + /** + * Alias for {@link #condition()}. + */ + @AliasFor("condition") + String value() default ""; + + /** + * Condition to disable test. + * + *
When case insensitive {@code String} "true" or {@code Boolean#TRUE} is returned, + * annotated test method or class is disabled. + *
SpEL expression can be used.
+ */
+ @AliasFor("value")
+ String condition() default "";
+
+ String reason() default "";
+
+}
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 8eef966a330f..d3a52c90c396 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
@@ -16,28 +16,39 @@
package org.springframework.test.context.junit.jupiter;
+import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
+import java.util.Optional;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.AfterEachCallback;
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.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.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.TestExecutionCondition;
import org.junit.jupiter.api.extension.TestExtensionContext;
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanExpressionContext;
+import org.springframework.beans.factory.config.BeanExpressionResolver;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.TestContextManager;
import org.springframework.util.Assert;
@@ -50,14 +61,17 @@
* {@code @ExtendWith(SpringExtension.class)}.
*
* @author Sam Brannen
+ * @author Tadaya Tsuyukubo
* @since 5.0
* @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig
* @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig
* @see org.springframework.test.context.TestContextManager
+ * @see DisabledIf
*/
public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor,
BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback,
- ParameterResolver {
+ ParameterResolver,
+ ContainerExecutionCondition, TestExecutionCondition {
/**
* {@link Namespace} in which {@code TestContextManagers} are stored, keyed
@@ -65,6 +79,12 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
*/
private static final Namespace namespace = Namespace.create(SpringExtension.class);
+ private static final ConditionEvaluationResult TEST_ENABLED = ConditionEvaluationResult.enabled(
+ "@DisabledIf condition didn't match");
+
+ private static final Log logger = LogFactory.getLog(SpringExtension.class);
+
+
/**
* Delegates to {@link TestContextManager#beforeTestClass}.
*/
@@ -175,6 +195,61 @@ public Object resolve(ParameterContext parameterContext, ExtensionContext extens
return ParameterAutowireUtils.resolveDependency(parameter, testClass, applicationContext);
}
+ @Override
+ public ConditionEvaluationResult evaluate(ContainerExtensionContext context) {
+ return evaluateDisabledIf(context);
+ }
+
+ @Override
+ public ConditionEvaluationResult evaluate(TestExtensionContext context) {
+ return evaluateDisabledIf(context);
+ }
+
+ private ConditionEvaluationResult evaluateDisabledIf(ExtensionContext extensionContext) {
+ Optional