001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.context.junit4.statements; 018 019import java.lang.annotation.Annotation; 020import java.lang.reflect.Method; 021 022import org.junit.AssumptionViolatedException; 023import org.junit.runners.model.Statement; 024 025import org.springframework.core.annotation.AnnotatedElementUtils; 026import org.springframework.test.annotation.IfProfileValue; 027import org.springframework.test.annotation.ProfileValueUtils; 028import org.springframework.util.Assert; 029 030/** 031 * {@code ProfileValueChecker} is a custom JUnit {@link Statement} that checks 032 * whether a test class or test method is enabled in the current environment 033 * via Spring's {@link IfProfileValue @IfProfileValue} annotation. 034 * 035 * @author Sam Brannen 036 * @author Philippe Marschall 037 * @since 4.2 038 * @see #evaluate() 039 * @see IfProfileValue 040 * @see ProfileValueUtils 041 */ 042public class ProfileValueChecker extends Statement { 043 044 private final Statement next; 045 046 private final Class<?> testClass; 047 048 private final Method testMethod; 049 050 051 /** 052 * Construct a new {@code ProfileValueChecker} statement. 053 * @param next the next {@code Statement} in the execution chain; 054 * never {@code null} 055 * @param testClass the test class to check; never {@code null} 056 * @param testMethod the test method to check; may be {@code null} if 057 * this {@code ProfileValueChecker} is being applied at the class level 058 */ 059 public ProfileValueChecker(Statement next, Class<?> testClass, Method testMethod) { 060 Assert.notNull(next, "The next statement must not be null"); 061 Assert.notNull(testClass, "The test class must not be null"); 062 this.next = next; 063 this.testClass = testClass; 064 this.testMethod = testMethod; 065 } 066 067 068 /** 069 * Determine if the test specified by arguments to the 070 * {@linkplain #ProfileValueChecker constructor} is <em>enabled</em> in 071 * the current environment, as configured via the {@link IfProfileValue 072 * @IfProfileValue} annotation. 073 * <p>If the test is not annotated with {@code @IfProfileValue} it is 074 * considered enabled. 075 * <p>If a test is not enabled, this method will abort further evaluation 076 * of the execution chain with a failed assumption; otherwise, this method 077 * will simply evaluate the next {@link Statement} in the execution chain. 078 * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) 079 * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class) 080 * @throws AssumptionViolatedException if the test is disabled 081 * @throws Throwable if evaluation of the next statement fails 082 */ 083 @Override 084 public void evaluate() throws Throwable { 085 if (this.testMethod == null) { 086 if (!ProfileValueUtils.isTestEnabledInThisEnvironment(this.testClass)) { 087 Annotation ann = AnnotatedElementUtils.findMergedAnnotation(this.testClass, IfProfileValue.class); 088 throw new AssumptionViolatedException(String.format( 089 "Profile configured via [%s] is not enabled in this environment for test class [%s].", 090 ann, this.testClass.getName())); 091 } 092 } 093 else { 094 if (!ProfileValueUtils.isTestEnabledInThisEnvironment(this.testMethod, this.testClass)) { 095 throw new AssumptionViolatedException(String.format( 096 "Profile configured via @IfProfileValue is not enabled in this environment for test method [%s].", 097 this.testMethod)); 098 } 099 } 100 101 this.next.evaluate(); 102 } 103 104}