Merge from sbrannen/SPR-7731
* SPR-7731: Introduce JUnit Rule alternative to SpringJUnit4ClassRunner
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.test.context.junit4;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -36,12 +37,12 @@ import org.springframework.test.context.web.ServletTestExecutionListener;
|
||||
* in a <strong>JUnit</strong> environment.
|
||||
*
|
||||
* <p>Concrete subclasses should typically declare a class-level
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation to
|
||||
* configure the {@link ApplicationContext application context} {@link
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation to
|
||||
* configure the {@linkplain ApplicationContext application context} {@link
|
||||
* ContextConfiguration#locations() resource locations} or {@link
|
||||
* ContextConfiguration#classes() annotated classes}. <em>If your test does not
|
||||
* need to load an application context, you may choose to omit the {@link
|
||||
* ContextConfiguration @ContextConfiguration} declaration and to configure
|
||||
* need to load an application context, you may choose to omit the
|
||||
* {@link ContextConfiguration @ContextConfiguration} declaration and to configure
|
||||
* the appropriate {@link org.springframework.test.context.TestExecutionListener
|
||||
* TestExecutionListeners} manually.</em>
|
||||
*
|
||||
@@ -54,12 +55,18 @@ import org.springframework.test.context.web.ServletTestExecutionListener;
|
||||
* <li>{@link org.springframework.test.context.support.DirtiesContextTestExecutionListener}
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note: this class serves only as a convenience for extension. If you do not
|
||||
* wish for your test classes to be tied to a Spring-specific class hierarchy,
|
||||
* you may configure your own custom test classes by using
|
||||
* {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration
|
||||
* @ContextConfiguration}, {@link TestExecutionListeners
|
||||
* @TestExecutionListeners}, etc.
|
||||
* <p>This class serves only as a convenience for extension.
|
||||
* <ul>
|
||||
* <li>If you do not wish for your test classes to be tied to a Spring-specific
|
||||
* class hierarchy, you may configure your own custom test classes by using
|
||||
* {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration @ContextConfiguration},
|
||||
* {@link TestExecutionListeners @TestExecutionListeners}, etc.</li>
|
||||
* <li>If you wish to extend this class and use a runner other than the
|
||||
* {@link SpringJUnit4ClassRunner}, as of Spring Framework 4.2 you can use
|
||||
* {@link org.springframework.test.context.junit4.rules.SpringClassRule SpringClassRule} and
|
||||
* {@link org.springframework.test.context.junit4.rules.SpringMethodRule SpringMethodRule}
|
||||
* and specify your runner of choice via {@link RunWith @RunWith(...)}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>NOTE:</strong> As of Spring Framework 4.1, this class requires JUnit 4.9 or higher.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -60,13 +60,18 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* <li>{@link org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener}
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note: this class serves only as a convenience for extension. If you do not
|
||||
* wish for your test classes to be tied to a Spring-specific class hierarchy,
|
||||
* you may configure your own custom test classes by using
|
||||
* {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration
|
||||
* @ContextConfiguration}, {@link TestExecutionListeners
|
||||
* @TestExecutionListeners}, {@link Transactional @Transactional},
|
||||
* etc.
|
||||
* <p>This class serves only as a convenience for extension.
|
||||
* <ul>
|
||||
* <li>If you do not wish for your test classes to be tied to a Spring-specific
|
||||
* class hierarchy, you may configure your own custom test classes by using
|
||||
* {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration @ContextConfiguration},
|
||||
* {@link TestExecutionListeners @TestExecutionListeners}, etc.</li>
|
||||
* <li>If you wish to extend this class and use a runner other than the
|
||||
* {@link SpringJUnit4ClassRunner}, as of Spring Framework 4.2 you can use
|
||||
* {@link org.springframework.test.context.junit4.rules.SpringClassRule SpringClassRule} and
|
||||
* {@link org.springframework.test.context.junit4.rules.SpringMethodRule SpringMethodRule}
|
||||
* and specify your runner of choice via {@link org.junit.runner.RunWith @RunWith(...)}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>NOTE:</strong> As of Spring Framework 4.1, this class requires JUnit 4.9 or higher.
|
||||
*
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -41,6 +42,8 @@ import org.springframework.test.annotation.ProfileValueUtils;
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.annotation.Timed;
|
||||
import org.springframework.test.context.TestContextManager;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks;
|
||||
import org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks;
|
||||
import org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks;
|
||||
@@ -72,6 +75,9 @@ import org.springframework.util.ReflectionUtils;
|
||||
* <li>{@link org.springframework.test.annotation.IfProfileValue @IfProfileValue}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If you would like to use the Spring TestContext Framework with a runner
|
||||
* other than this one, use {@link SpringClassRule} and {@link SpringMethodRule}.
|
||||
*
|
||||
* <p><strong>NOTE:</strong> As of Spring Framework 4.1, this class requires JUnit 4.9 or higher.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
@@ -80,6 +86,8 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @see TestContextManager
|
||||
* @see AbstractJUnit4SpringContextTests
|
||||
* @see AbstractTransactionalJUnit4SpringContextTests
|
||||
* @see org.springframework.test.context.junit4.rules.SpringClassRule
|
||||
* @see org.springframework.test.context.junit4.rules.SpringMethodRule
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
@@ -101,6 +109,19 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
private final TestContextManager testContextManager;
|
||||
|
||||
|
||||
private static void ensureSpringRulesAreNotPresent(Class<?> testClass) {
|
||||
for (Field field : testClass.getFields()) {
|
||||
if (SpringClassRule.class.isAssignableFrom(field.getType())) {
|
||||
throw new IllegalStateException(String.format("Detected SpringClassRule field in test class [%s], but "
|
||||
+ "SpringClassRule cannot be used with the SpringJUnit4ClassRunner.", testClass.getName()));
|
||||
}
|
||||
if (SpringMethodRule.class.isAssignableFrom(field.getType())) {
|
||||
throw new IllegalStateException(String.format("Detected SpringMethodRule field in test class [%s], "
|
||||
+ "but SpringMethodRule cannot be used with the SpringJUnit4ClassRunner.", testClass.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code SpringJUnit4ClassRunner} and initialize a
|
||||
* {@link TestContextManager} to provide Spring testing functionality to
|
||||
@@ -113,6 +134,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("SpringJUnit4ClassRunner constructor called with [" + clazz + "].");
|
||||
}
|
||||
ensureSpringRulesAreNotPresent(clazz);
|
||||
this.testContextManager = createTestContextManager(clazz);
|
||||
}
|
||||
|
||||
@@ -166,7 +188,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
/**
|
||||
* Wrap the {@link Statement} returned by the parent implementation with a
|
||||
* {@link RunBeforeTestClassCallbacks} statement, thus preserving the
|
||||
* {@code RunBeforeTestClassCallbacks} statement, thus preserving the
|
||||
* default JUnit functionality while adding support for the Spring TestContext
|
||||
* Framework.
|
||||
* @see RunBeforeTestClassCallbacks
|
||||
@@ -179,7 +201,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
/**
|
||||
* Wrap the {@link Statement} returned by the parent implementation with a
|
||||
* {@link RunAfterTestClassCallbacks} statement, thus preserving the default
|
||||
* {@code RunAfterTestClassCallbacks} statement, thus preserving the default
|
||||
* JUnit functionality while adding support for the Spring TestContext Framework.
|
||||
* @see RunAfterTestClassCallbacks
|
||||
*/
|
||||
@@ -393,7 +415,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
/**
|
||||
* Wrap the {@link Statement} returned by the parent implementation with a
|
||||
* {@link RunBeforeTestMethodCallbacks} statement, thus preserving the
|
||||
* {@code RunBeforeTestMethodCallbacks} statement, thus preserving the
|
||||
* default functionality while adding support for the Spring TestContext
|
||||
* Framework.
|
||||
* @see RunBeforeTestMethodCallbacks
|
||||
@@ -407,7 +429,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
/**
|
||||
* Wrap the {@link Statement} returned by the parent implementation with a
|
||||
* {@link RunAfterTestMethodCallbacks} statement, thus preserving the
|
||||
* {@code RunAfterTestMethodCallbacks} statement, thus preserving the
|
||||
* default functionality while adding support for the Spring TestContext
|
||||
* Framework.
|
||||
* @see RunAfterTestMethodCallbacks
|
||||
@@ -423,10 +445,10 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||
* Return a {@link Statement} that potentially repeats the execution of
|
||||
* the {@code next} statement.
|
||||
* <p>Supports Spring's {@link Repeat @Repeat} annotation by returning a
|
||||
* {@link SpringRepeat} statement initialized with the configured repeat
|
||||
* {@code SpringRepeat} statement initialized with the configured repeat
|
||||
* count (if greater than {@code 1}); otherwise, the supplied statement
|
||||
* is returned unmodified.
|
||||
* @return either a {@link SpringRepeat} or the supplied {@link Statement}
|
||||
* @return either a {@code SpringRepeat} or the supplied {@code Statement}
|
||||
* as appropriate
|
||||
* @see SpringRepeat
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.test.context.TestContextManager;
|
||||
import org.springframework.test.context.junit4.statements.ProfileValueChecker;
|
||||
import org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks;
|
||||
import org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks;
|
||||
|
||||
/**
|
||||
* {@code SpringClassRule} is a custom JUnit {@link TestRule} that provides
|
||||
* <em>class-level</em> functionality of the <em>Spring TestContext Framework</em>
|
||||
* to standard JUnit tests by means of the {@link TestContextManager} and associated
|
||||
* support classes and annotations.
|
||||
*
|
||||
* <p>In contrast to the {@link org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* SpringJUnit4ClassRunner}, Spring's rule-based JUnit support has the advantage
|
||||
* that it is independent of any {@link org.junit.runner.Runner Runner} and
|
||||
* can therefore be combined with existing alternative runners like JUnit's
|
||||
* {@code Parameterized} or third-party runners such as the {@code MockitoJUnitRunner}.
|
||||
*
|
||||
* <p>In order to achieve the same functionality as the {@code SpringJUnit4ClassRunner},
|
||||
* however, a {@code SpringClassRule} must be combined with a {@link SpringMethodRule},
|
||||
* since {@code SpringClassRule} only provides the class-level features of the
|
||||
* {@code SpringJUnit4ClassRunner}.
|
||||
*
|
||||
* <h3>Example Usage</h3>
|
||||
* <pre><code> public class ExampleSpringIntegrationTest {
|
||||
*
|
||||
* @ClassRule
|
||||
* public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
*
|
||||
* @Rule
|
||||
* public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
*
|
||||
* // ...
|
||||
* }</code></pre>
|
||||
*
|
||||
* <p>The following list constitutes all annotations currently supported directly
|
||||
* or indirectly by {@code SpringClassRule}. <em>(Note that additional annotations
|
||||
* may be supported by various
|
||||
* {@link org.springframework.test.context.TestExecutionListener TestExecutionListener} or
|
||||
* {@link org.springframework.test.context.TestContextBootstrapper TestContextBootstrapper}
|
||||
* implementations.)</em>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link org.springframework.test.annotation.ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}</li>
|
||||
* <li>{@link org.springframework.test.annotation.IfProfileValue @IfProfileValue}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>NOTE:</strong> This class requires JUnit 4.9 or higher.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Philippe Marschall
|
||||
* @since 4.2
|
||||
* @see #apply(Statement, Description)
|
||||
* @see SpringMethodRule
|
||||
* @see org.springframework.test.context.TestContextManager
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
*/
|
||||
public class SpringClassRule implements TestRule {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpringClassRule.class);
|
||||
|
||||
/**
|
||||
* This field is {@code volatile} since a {@code SpringMethodRule} can
|
||||
* potentially access it from a different thread, depending on the type
|
||||
* of JUnit runner in use.
|
||||
*/
|
||||
private volatile TestContextManager testContextManager;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link TestContextManager} for the supplied test class.
|
||||
* <p>Can be overridden by subclasses.
|
||||
* @param clazz the test class to be managed
|
||||
*/
|
||||
protected TestContextManager createTestContextManager(Class<?> clazz) {
|
||||
return new TestContextManager(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link TestContextManager} associated with this rule.
|
||||
* <p>Will be {@code null} until the {@link #apply} method is invoked
|
||||
* by a JUnit runner.
|
||||
*/
|
||||
protected final TestContextManager getTestContextManager() {
|
||||
return this.testContextManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply <em>class-level</em> functionality of the <em>Spring TestContext
|
||||
* Framework</em> to the supplied {@code base} statement.
|
||||
*
|
||||
* <p>Specifically, this method creates the {@link TestContextManager} used
|
||||
* by this rule and its associated {@link SpringMethodRule} and invokes the
|
||||
* {@link TestContextManager#beforeTestClass() beforeTestClass()} and
|
||||
* {@link TestContextManager#afterTestClass() afterTestClass()} methods
|
||||
* on the {@code TestContextManager}.
|
||||
*
|
||||
* <p>In addition, this method checks whether the test is enabled in
|
||||
* the current execution environment. This prevents classes with a
|
||||
* non-matching {@code @IfProfileValue} annotation from running altogether,
|
||||
* even skipping the execution of {@code beforeTestClass()} methods
|
||||
* in {@code TestExecutionListeners}.
|
||||
*
|
||||
* @param base the base {@code Statement} that this rule should be applied to
|
||||
* @param description a {@code Description} of the current test execution
|
||||
* @return a statement that wraps the supplied {@code base} with class-level
|
||||
* functionality of the Spring TestContext Framework
|
||||
* @see #createTestContextManager
|
||||
* @see #withBeforeTestClassCallbacks
|
||||
* @see #withAfterTestClassCallbacks
|
||||
* @see #withProfileValueCheck
|
||||
*/
|
||||
@Override
|
||||
public Statement apply(final Statement base, final Description description) {
|
||||
Class<?> testClass = description.getTestClass();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Applying SpringClassRule to test class [" + testClass.getName() + "].");
|
||||
}
|
||||
|
||||
validateSpringMethodRuleConfiguration(testClass);
|
||||
|
||||
this.testContextManager = createTestContextManager(testClass);
|
||||
|
||||
Statement statement = base;
|
||||
statement = withBeforeTestClassCallbacks(statement);
|
||||
statement = withAfterTestClassCallbacks(statement);
|
||||
statement = withProfileValueCheck(testClass, statement);
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@code statement} with a {@code RunBeforeTestClassCallbacks} statement.
|
||||
* @see RunBeforeTestClassCallbacks
|
||||
*/
|
||||
protected Statement withBeforeTestClassCallbacks(Statement statement) {
|
||||
return new RunBeforeTestClassCallbacks(statement, getTestContextManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@code statement} with a {@code RunAfterTestClassCallbacks} statement.
|
||||
* @see RunAfterTestClassCallbacks
|
||||
*/
|
||||
protected Statement withAfterTestClassCallbacks(Statement statement) {
|
||||
return new RunAfterTestClassCallbacks(statement, getTestContextManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@code statement} with a {@code ProfileValueChecker} statement.
|
||||
* @see ProfileValueChecker
|
||||
*/
|
||||
protected Statement withProfileValueCheck(Class<?> testClass, Statement statement) {
|
||||
return new ProfileValueChecker(statement, testClass, null);
|
||||
}
|
||||
|
||||
private void validateSpringMethodRuleConfiguration(Class<?> testClass) {
|
||||
Field ruleField = null;
|
||||
|
||||
for (Field field : testClass.getFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)
|
||||
&& (SpringMethodRule.class.isAssignableFrom(field.getType()))) {
|
||||
ruleField = field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ruleField == null) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Failed to find 'public SpringMethodRule' field in test class [%s]. "
|
||||
+ "Consult the Javadoc for SpringClassRule for details.", testClass.getName()));
|
||||
}
|
||||
|
||||
if (!ruleField.isAnnotationPresent(Rule.class)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"SpringMethodRule field [%s] must be annotated with JUnit's @Rule annotation. "
|
||||
+ "Consult the Javadoc for SpringClassRule for details.", ruleField));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.rules.MethodRule;
|
||||
import org.junit.runners.model.FrameworkMethod;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.annotation.Timed;
|
||||
import org.springframework.test.context.TestContextManager;
|
||||
import org.springframework.test.context.junit4.statements.ProfileValueChecker;
|
||||
import org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks;
|
||||
import org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks;
|
||||
import org.springframework.test.context.junit4.statements.RunPrepareTestInstanceCallbacks;
|
||||
import org.springframework.test.context.junit4.statements.SpringFailOnTimeout;
|
||||
import org.springframework.test.context.junit4.statements.SpringRepeat;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* {@code SpringMethodRule} is a custom JUnit {@link MethodRule} that
|
||||
* provides instance-level and method-level functionality of the
|
||||
* <em>Spring TestContext Framework</em> to standard JUnit tests by means
|
||||
* of the {@link TestContextManager} and associated support classes and
|
||||
* annotations.
|
||||
*
|
||||
* <p>In contrast to the {@link org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* SpringJUnit4ClassRunner}, Spring's rule-based JUnit support has the advantage
|
||||
* that it is independent of any {@link org.junit.runner.Runner Runner} and
|
||||
* can therefore be combined with existing alternative runners like JUnit's
|
||||
* {@code Parameterized} or third-party runners such as the {@code MockitoJUnitRunner}.
|
||||
*
|
||||
* <p>In order to achieve the same functionality as the {@code SpringJUnit4ClassRunner},
|
||||
* however, a {@code SpringMethodRule} must be combined with a {@link SpringClassRule},
|
||||
* since {@code SpringMethodRule} only provides the method-level features of the
|
||||
* {@code SpringJUnit4ClassRunner}.
|
||||
*
|
||||
* <h3>Example Usage</h3>
|
||||
* <pre><code> public class ExampleSpringIntegrationTest {
|
||||
*
|
||||
* @ClassRule
|
||||
* public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
*
|
||||
* @Rule
|
||||
* public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
*
|
||||
* // ...
|
||||
* }</code></pre>
|
||||
*
|
||||
* <p>The following list constitutes all annotations currently supported directly
|
||||
* or indirectly by {@code SpringMethodRule}. <em>(Note that additional annotations
|
||||
* may be supported by various
|
||||
* {@link org.springframework.test.context.TestExecutionListener TestExecutionListener} or
|
||||
* {@link org.springframework.test.context.TestContextBootstrapper TestContextBootstrapper}
|
||||
* implementations.)</em>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link Timed @Timed}</li>
|
||||
* <li>{@link Repeat @Repeat}</li>
|
||||
* <li>{@link org.springframework.test.annotation.ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}</li>
|
||||
* <li>{@link org.springframework.test.annotation.IfProfileValue @IfProfileValue}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>NOTE:</strong> This class requires JUnit 4.9 or higher.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Philippe Marschall
|
||||
* @since 4.2
|
||||
* @see #apply(Statement, FrameworkMethod, Object)
|
||||
* @see SpringClassRule
|
||||
* @see org.springframework.test.context.TestContextManager
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
*/
|
||||
public class SpringMethodRule implements MethodRule {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpringMethodRule.class);
|
||||
|
||||
/**
|
||||
* {@code SpringMethodRule} retains a reference to the {@code SpringClassRule}
|
||||
* instead of the {@code TestContextManager}, since the class rule <em>owns</em>
|
||||
* the {@code TestContextManager}.
|
||||
*/
|
||||
private final SpringClassRule springClassRule;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code SpringMethodRule} for the supplied test instance.
|
||||
*
|
||||
* <p>The test class must declare a {@code public static final SpringClassRule}
|
||||
* field (i.e., a <em>constant</em>) that is annotated with JUnit's
|
||||
* {@link ClassRule @ClassRule} — for example:
|
||||
*
|
||||
* <pre><code> @ClassRule
|
||||
* public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();</code></pre>
|
||||
*
|
||||
* @param testInstance the test instance, never {@code null}
|
||||
* @throws IllegalStateException if the test class does not declare an
|
||||
* appropriate {@code SpringClassRule} constant.
|
||||
*/
|
||||
public SpringMethodRule(Object testInstance) {
|
||||
Assert.notNull(testInstance, "testInstance must not be null");
|
||||
this.springClassRule = retrieveAndValidateSpringClassRule(testInstance.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply <em>instance-level</em> and <em>method-level</em> functionality
|
||||
* of the <em>Spring TestContext Framework</em> to the supplied {@code base}
|
||||
* statement.
|
||||
*
|
||||
* <p>Specifically, this method invokes the
|
||||
* {@link TestContextManager#prepareTestInstance prepareTestInstance()},
|
||||
* {@link TestContextManager#beforeTestMethod beforeTestMethod()}, and
|
||||
* {@link TestContextManager#afterTestMethod afterTestMethod()} methods
|
||||
* on the {@code TestContextManager}, potentially with Spring timeouts
|
||||
* and repetitions.
|
||||
*
|
||||
* <p>In addition, this method checks whether the test is enabled in
|
||||
* the current execution environment. This prevents methods with a
|
||||
* non-matching {@code @IfProfileValue} annotation from running altogether,
|
||||
* even skipping the execution of {@code prepareTestInstance()} methods
|
||||
* in {@code TestExecutionListeners}.
|
||||
*
|
||||
* @param base the base {@code Statement} that this rule should be applied to
|
||||
* @param frameworkMethod the method which is about to be invoked on the test instance
|
||||
* @param testInstance the current test instance
|
||||
* @return a statement that wraps the supplied {@code base} with instance-level
|
||||
* and method-level functionality of the Spring TestContext Framework
|
||||
* @see #withBeforeTestMethodCallbacks
|
||||
* @see #withAfterTestMethodCallbacks
|
||||
* @see #withPotentialRepeat
|
||||
* @see #withPotentialTimeout
|
||||
* @see #withTestInstancePreparation
|
||||
* @see #withProfileValueCheck
|
||||
*/
|
||||
@Override
|
||||
public Statement apply(final Statement base, final FrameworkMethod frameworkMethod, final Object testInstance) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Applying SpringMethodRule to test method [" + frameworkMethod.getMethod() + "].");
|
||||
}
|
||||
|
||||
Statement statement = base;
|
||||
statement = withBeforeTestMethodCallbacks(frameworkMethod, testInstance, statement);
|
||||
statement = withAfterTestMethodCallbacks(frameworkMethod, testInstance, statement);
|
||||
statement = withTestInstancePreparation(testInstance, statement);
|
||||
statement = withPotentialRepeat(frameworkMethod, testInstance, statement);
|
||||
statement = withPotentialTimeout(frameworkMethod, testInstance, statement);
|
||||
statement = withProfileValueCheck(frameworkMethod, testInstance, statement);
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link TestContextManager} associated with this rule.
|
||||
*/
|
||||
protected final TestContextManager getTestContextManager() {
|
||||
return this.springClassRule.getTestContextManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@link Statement} with a {@code ProfileValueChecker} statement.
|
||||
* @see ProfileValueChecker
|
||||
*/
|
||||
protected Statement withProfileValueCheck(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
|
||||
return new ProfileValueChecker(statement, testInstance.getClass(), frameworkMethod.getMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@link Statement} with a {@code RunPrepareTestInstanceCallbacks} statement.
|
||||
* @see RunPrepareTestInstanceCallbacks
|
||||
*/
|
||||
protected Statement withTestInstancePreparation(Object testInstance, Statement statement) {
|
||||
return new RunPrepareTestInstanceCallbacks(statement, testInstance, getTestContextManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@link Statement} with a {@code RunBeforeTestMethodCallbacks} statement.
|
||||
* @see RunBeforeTestMethodCallbacks
|
||||
*/
|
||||
protected Statement withBeforeTestMethodCallbacks(FrameworkMethod frameworkMethod, Object testInstance,
|
||||
Statement statement) {
|
||||
return new RunBeforeTestMethodCallbacks(statement, testInstance, frameworkMethod.getMethod(),
|
||||
getTestContextManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the supplied {@link Statement} with a {@code RunAfterTestMethodCallbacks} statement.
|
||||
* @see RunAfterTestMethodCallbacks
|
||||
*/
|
||||
protected Statement withAfterTestMethodCallbacks(FrameworkMethod frameworkMethod, Object testInstance,
|
||||
Statement statement) {
|
||||
return new RunAfterTestMethodCallbacks(statement, testInstance, frameworkMethod.getMethod(),
|
||||
getTestContextManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Statement} that potentially repeats the execution of
|
||||
* the {@code next} statement.
|
||||
* <p>Supports Spring's {@link Repeat @Repeat} annotation by returning a
|
||||
* {@link SpringRepeat} statement initialized with the configured repeat
|
||||
* count (if greater than {@code 1}); otherwise, the supplied statement
|
||||
* is returned unmodified.
|
||||
* @return either a {@code SpringRepeat} or the supplied {@code Statement}
|
||||
* @see SpringRepeat
|
||||
*/
|
||||
protected Statement withPotentialRepeat(FrameworkMethod frameworkMethod, Object testInstance, Statement next) {
|
||||
Repeat repeatAnnotation = AnnotationUtils.getAnnotation(frameworkMethod.getMethod(), Repeat.class);
|
||||
int repeat = (repeatAnnotation != null ? repeatAnnotation.value() : 1);
|
||||
return (repeat > 1 ? new SpringRepeat(next, frameworkMethod.getMethod(), repeat) : next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Statement} that potentially throws an exception if
|
||||
* the {@code next} statement in the execution chain takes longer than
|
||||
* a specified timeout.
|
||||
* <p>Supports Spring's {@link Timed @Timed} annotation by returning a
|
||||
* {@link SpringFailOnTimeout} statement initialized with the configured
|
||||
* timeout (if greater than {@code 0}); otherwise, the supplied statement
|
||||
* is returned unmodified.
|
||||
* @return either a {@code SpringFailOnTimeout} or the supplied {@code Statement}
|
||||
* @see #getSpringTimeout(FrameworkMethod)
|
||||
* @see SpringFailOnTimeout
|
||||
*/
|
||||
protected Statement withPotentialTimeout(FrameworkMethod frameworkMethod, Object testInstance, Statement next) {
|
||||
long springTimeout = getSpringTimeout(frameworkMethod);
|
||||
return (springTimeout > 0 ? new SpringFailOnTimeout(next, springTimeout) : next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the configured Spring-specific {@code timeout} from the
|
||||
* {@link Timed @Timed} annotation on the supplied
|
||||
* {@linkplain FrameworkMethod test method}.
|
||||
* @return the timeout, or {@code 0} if none was specified
|
||||
*/
|
||||
protected long getSpringTimeout(FrameworkMethod frameworkMethod) {
|
||||
AnnotationAttributes annAttrs = AnnotatedElementUtils.findAnnotationAttributes(frameworkMethod.getMethod(),
|
||||
Timed.class.getName());
|
||||
if (annAttrs == null) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
long millis = annAttrs.<Long> getNumber("millis").longValue();
|
||||
return millis > 0 ? millis : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static SpringClassRule retrieveAndValidateSpringClassRule(Class<?> testClass) {
|
||||
Field springClassRuleField = null;
|
||||
|
||||
for (Field field : testClass.getFields()) {
|
||||
if (ReflectionUtils.isPublicStaticFinal(field) && (SpringClassRule.class.isAssignableFrom(field.getType()))) {
|
||||
springClassRuleField = field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (springClassRuleField == null) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Failed to find 'public static final SpringClassRule' field in test class [%s]. "
|
||||
+ "Consult the Javadoc for SpringClassRule for details.", testClass.getName()));
|
||||
}
|
||||
|
||||
if (!springClassRuleField.isAnnotationPresent(ClassRule.class)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"SpringClassRule field [%s] must be annotated with JUnit's @ClassRule annotation. "
|
||||
+ "Consult the Javadoc for SpringClassRule for details.", springClassRuleField));
|
||||
}
|
||||
|
||||
return (SpringClassRule) ReflectionUtils.getField(springClassRuleField, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Custom JUnit {@code Rules} used in the <em>Spring TestContext Framework</em>.
|
||||
*/
|
||||
package org.springframework.test.context.junit4.rules;
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.statements;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.annotation.ProfileValueUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@code ProfileValueChecker} is a custom JUnit {@link Statement} that checks
|
||||
* whether a test class or test method is enabled in the current environment
|
||||
* via Spring's {@link IfProfileValue @IfProfileValue} annotation.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Philippe Marschall
|
||||
* @since 4.2
|
||||
* @see #evaluate()
|
||||
* @see IfProfileValue
|
||||
* @see ProfileValueUtils
|
||||
*/
|
||||
public class ProfileValueChecker extends Statement {
|
||||
|
||||
private final Statement next;
|
||||
|
||||
private final Class<?> testClass;
|
||||
|
||||
private final Method testMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code ProfileValueChecker} statement.
|
||||
*
|
||||
* @param next the next {@code Statement} in the execution chain; never
|
||||
* {@code null}
|
||||
* @param testClass the test class to check; never {@code null}
|
||||
* @param testMethod the test method to check; may be {@code null} if
|
||||
* this {@code ProfileValueChecker} is being applied at the class level
|
||||
*/
|
||||
public ProfileValueChecker(Statement next, Class<?> testClass, Method testMethod) {
|
||||
Assert.notNull(next, "The next statement must not be null");
|
||||
Assert.notNull(testClass, "The test class must not be null");
|
||||
this.next = next;
|
||||
this.testClass = testClass;
|
||||
this.testMethod = testMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the test specified by arguments to the
|
||||
* {@linkplain #ProfileValueChecker constructor} is <em>enabled</em> in
|
||||
* the current environment, as configured via the {@link IfProfileValue
|
||||
* @IfProfileValue} annotation.
|
||||
* <p>If the test is not annotated with {@code @IfProfileValue} it is
|
||||
* considered enabled.
|
||||
* <p>If a test is not enabled, this method will abort further evaluation
|
||||
* of the execution chain with a failed assumption; otherwise, this method
|
||||
* will simply evaluate the next {@link Statement} in the execution chain.
|
||||
* @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class)
|
||||
* @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class)
|
||||
* @see org.junit.Assume
|
||||
*/
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
if (this.testMethod == null) {
|
||||
if (!ProfileValueUtils.isTestEnabledInThisEnvironment(testClass)) {
|
||||
// Invoke assumeTrue() with false to avoid direct reference to JUnit's
|
||||
// AssumptionViolatedException which exists in two packages as of JUnit 4.12.
|
||||
Assume.assumeTrue(String.format(
|
||||
"Profile configured via [%s] is not enabled in this environment for test class [%s].",
|
||||
AnnotationUtils.findAnnotation(testClass, IfProfileValue.class), testClass.getName()), false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!ProfileValueUtils.isTestEnabledInThisEnvironment(testMethod, testClass)) {
|
||||
// Invoke assumeTrue() with false to avoid direct reference to JUnit's
|
||||
// AssumptionViolatedException which exists in two packages as of JUnit 4.12.
|
||||
Assume.assumeTrue(String.format(
|
||||
"Profile configured via @IfProfileValue is not enabled in this environment for test method [%s].",
|
||||
testMethod), false);
|
||||
}
|
||||
}
|
||||
|
||||
this.next.evaluate();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,13 +25,15 @@ import org.junit.runners.model.Statement;
|
||||
import org.springframework.test.context.TestContextManager;
|
||||
|
||||
/**
|
||||
* {@code RunAfterTestClassCallbacks} is a custom JUnit {@link Statement} which allows the
|
||||
* <em>Spring TestContext Framework</em> to be plugged into the JUnit execution chain by
|
||||
* calling {@link TestContextManager#afterTestClass() afterTestClass()} on the supplied
|
||||
* {@code RunAfterTestClassCallbacks} is a custom JUnit {@link Statement} which allows
|
||||
* the <em>Spring TestContext Framework</em> to be plugged into the JUnit execution chain
|
||||
* by calling {@link TestContextManager#afterTestClass afterTestClass()} on the supplied
|
||||
* {@link TestContextManager}.
|
||||
*
|
||||
* <p><strong>NOTE:</strong> This class requires JUnit 4.9 or higher.
|
||||
*
|
||||
* @see #evaluate()
|
||||
* @see RunBeforeTestMethodCallbacks
|
||||
* @see RunBeforeTestClassCallbacks
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
@@ -28,8 +28,10 @@ import org.springframework.test.context.TestContextManager;
|
||||
/**
|
||||
* {@code RunAfterTestMethodCallbacks} is a custom JUnit {@link Statement} which allows
|
||||
* the <em>Spring TestContext Framework</em> to be plugged into the JUnit execution chain
|
||||
* by calling {@link TestContextManager#afterTestMethod(Object, Method, Throwable)
|
||||
* afterTestMethod()} on the supplied {@link TestContextManager}.
|
||||
* by calling {@link TestContextManager#afterTestMethod afterTestMethod()} on the supplied
|
||||
* {@link TestContextManager}.
|
||||
*
|
||||
* <p><strong>NOTE:</strong> This class requires JUnit 4.9 or higher.
|
||||
*
|
||||
* @see #evaluate()
|
||||
* @see RunBeforeTestMethodCallbacks
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.statements;
|
||||
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.test.context.TestContextManager;
|
||||
|
||||
/**
|
||||
* {@code RunPrepareTestInstanceCallbacks} is a custom JUnit {@link Statement} which
|
||||
* allows the <em>Spring TestContext Framework</em> to be plugged into the JUnit
|
||||
* execution chain by calling {@link TestContextManager#prepareTestInstance(Object)
|
||||
* prepareTestInstance()} on the supplied {@link TestContextManager}.
|
||||
*
|
||||
* @see #evaluate()
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
public class RunPrepareTestInstanceCallbacks extends Statement {
|
||||
|
||||
private final Statement next;
|
||||
|
||||
private final Object testInstance;
|
||||
|
||||
private final TestContextManager testContextManager;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code RunPrepareTestInstanceCallbacks} statement.
|
||||
*
|
||||
* @param next the next {@code Statement} in the execution chain; never {@code null}
|
||||
* @param testInstance the current test instance; never {@code null}
|
||||
* @param testContextManager the {@code TestContextManager} upon which to call
|
||||
* {@code prepareTestInstance()}; never {@code null}
|
||||
*/
|
||||
public RunPrepareTestInstanceCallbacks(Statement next, Object testInstance, TestContextManager testContextManager) {
|
||||
this.next = next;
|
||||
this.testInstance = testInstance;
|
||||
this.testContextManager = testContextManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke {@link TestContextManager#prepareTestInstance(Object)} and
|
||||
* then evaluate the next {@link Statement} in the execution chain
|
||||
* (typically an instance of {@link RunAfterTestMethodCallbacks}).
|
||||
*/
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
this.testContextManager.prepareTestInstance(testInstance);
|
||||
this.next.evaluate();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,11 @@ import org.springframework.test.annotation.Timed;
|
||||
* if the next statement in the execution chain takes more than the specified
|
||||
* number of milliseconds.
|
||||
*
|
||||
* <p>In contrast to JUnit's
|
||||
* {@link org.junit.internal.runners.statements.FailOnTimeout FailOnTimeout},
|
||||
* the next {@code statement} will be executed in the same thread as the
|
||||
* caller and will therefore not be aborted preemptively.
|
||||
*
|
||||
* @see #evaluate()
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
@@ -53,11 +58,9 @@ public class SpringFailOnTimeout extends Statement {
|
||||
|
||||
/**
|
||||
* Evaluate the next {@link Statement statement} in the execution chain
|
||||
* (typically an instance of
|
||||
* {@link org.junit.internal.runners.statements.InvokeMethod InvokeMethod}
|
||||
* or {@link org.junit.internal.runners.statements.ExpectException
|
||||
* ExpectException}) and throw a {@link TimeoutException} if the next
|
||||
* {@code statement} executes longer than the specified {@code timeout}.
|
||||
* (typically an instance of {@link SpringRepeat}) and throw a
|
||||
* {@link TimeoutException} if the next {@code statement} executes longer
|
||||
* than the specified {@code timeout}.
|
||||
*/
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
@@ -31,7 +29,6 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
* @see ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests
|
||||
* @see RelativePathSpringJUnit4ClassRunnerAppCtxTests
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { SpringJUnit4ClassRunnerAppCtxTests.DEFAULT_CONTEXT_RESOURCE_PATH }, inheritLocations = false)
|
||||
public class AbsolutePathSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests {
|
||||
/* all tests are in the parent class. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -19,10 +19,13 @@ package org.springframework.test.context.junit4;
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -56,6 +59,9 @@ public class BeforeAndAfterTransactionAnnotationTests extends AbstractTransactio
|
||||
|
||||
protected boolean inTransaction = false;
|
||||
|
||||
@Rule
|
||||
public final TestName testName = new TestName();
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
@@ -94,10 +100,21 @@ public class BeforeAndAfterTransactionAnnotationTests extends AbstractTransactio
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
assertShouldBeInTransaction();
|
||||
assertEquals("Verifying the number of rows in the person table before a test method.", (this.inTransaction ? 1
|
||||
: 0), countRowsInPersonTable(jdbcTemplate));
|
||||
}
|
||||
|
||||
private void assertShouldBeInTransaction() {
|
||||
boolean shouldBeInTransaction = !testName.getMethodName().equals("nonTransactionalMethod");
|
||||
assertInTransaction(shouldBeInTransaction);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
assertShouldBeInTransaction();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void transactionalMethod1() {
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
@@ -33,7 +31,6 @@ import org.springframework.util.ResourceUtils;
|
||||
* @see AbsolutePathSpringJUnit4ClassRunnerAppCtxTests
|
||||
* @see RelativePathSpringJUnit4ClassRunnerAppCtxTests
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests.CLASSPATH_CONTEXT_RESOURCE_PATH })
|
||||
public class ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests {
|
||||
|
||||
|
||||
@@ -43,23 +43,19 @@ public class ExpectedExceptionSpringRunnerTests {
|
||||
|
||||
@Test
|
||||
public void expectedExceptions() throws Exception {
|
||||
Class<ExpectedExceptionSpringRunnerTestCase> testClass = ExpectedExceptionSpringRunnerTestCase.class;
|
||||
Class<?> testClass = ExpectedExceptionSpringRunnerTestCase.class;
|
||||
TrackingRunListener listener = new TrackingRunListener();
|
||||
RunNotifier notifier = new RunNotifier();
|
||||
notifier.addListener(listener);
|
||||
|
||||
new SpringJUnit4ClassRunner(testClass).run(notifier);
|
||||
assertEquals("Verifying number of failures for test class [" + testClass + "].", 0,
|
||||
listener.getTestFailureCount());
|
||||
assertEquals("Verifying number of tests started for test class [" + testClass + "].", 1,
|
||||
listener.getTestStartedCount());
|
||||
assertEquals("Verifying number of tests finished for test class [" + testClass + "].", 1,
|
||||
listener.getTestFinishedCount());
|
||||
assertEquals("failures for test class [" + testClass + "].", 0, listener.getTestFailureCount());
|
||||
assertEquals("tests started for test class [" + testClass + "].", 1, listener.getTestStartedCount());
|
||||
assertEquals("tests finished for test class [" + testClass + "].", 1, listener.getTestFinishedCount());
|
||||
}
|
||||
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@TestExecutionListeners({})
|
||||
public static final class ExpectedExceptionSpringRunnerTestCase {
|
||||
|
||||
|
||||
@@ -16,16 +16,17 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runner.Runner;
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
@@ -33,30 +34,26 @@ import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
import org.springframework.test.context.transaction.AfterTransaction;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* JUnit 4 based integration test for verifying that '<i>before</i>' and '<i>after</i>'
|
||||
* methods of {@link TestExecutionListener TestExecutionListeners} as well as
|
||||
* {@link BeforeTransaction @BeforeTransaction} and
|
||||
* {@link AfterTransaction @AfterTransaction} methods can fail a test in a
|
||||
* JUnit 4.4 environment, as requested in <a
|
||||
* href="http://opensource.atlassian.com/projects/spring/browse/SPR-3960"
|
||||
* target="_blank">SPR-3960</a>.
|
||||
* </p>
|
||||
* <p>
|
||||
* Indirectly, this class also verifies that all {@link TestExecutionListener}
|
||||
* JUnit environment, as requested in
|
||||
* <a href="https://jira.spring.io/browse/SPR-3960" target="_blank">SPR-3960</a>.
|
||||
*
|
||||
* <p>Indirectly, this class also verifies that all {@link TestExecutionListener}
|
||||
* lifecycle callbacks are called.
|
||||
* </p>
|
||||
* <p>
|
||||
* As of Spring 3.0, this class also tests support for the new
|
||||
*
|
||||
* <p>As of Spring 3.0, this class also tests support for the new
|
||||
* {@link TestExecutionListener#beforeTestClass(TestContext) beforeTestClass()}
|
||||
* and {@link TestExecutionListener#afterTestClass(TestContext)
|
||||
* afterTestClass()} lifecycle callback methods.
|
||||
* </p>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
@@ -68,38 +65,42 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Collection<Object[]> testData() {
|
||||
return Arrays.asList(new Object[][] {//
|
||||
//
|
||||
{ AlwaysFailingBeforeTestClassTestCase.class.getSimpleName() },//
|
||||
{ AlwaysFailingAfterTestClassTestCase.class.getSimpleName() },//
|
||||
{ AlwaysFailingPrepareTestInstanceTestCase.class.getSimpleName() },//
|
||||
{ AlwaysFailingBeforeTestMethodTestCase.class.getSimpleName() },//
|
||||
{ AlwaysFailingAfterTestMethodTestCase.class.getSimpleName() },//
|
||||
{ FailingBeforeTransactionTestCase.class.getSimpleName() },//
|
||||
{ FailingAfterTransactionTestCase.class.getSimpleName() } //
|
||||
});
|
||||
public static Object[] testData() {
|
||||
return new Object[] {//
|
||||
AlwaysFailingBeforeTestClassTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingAfterTestClassTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingPrepareTestInstanceTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingBeforeTestMethodTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingAfterTestMethodTestCase.class.getSimpleName(),//
|
||||
FailingBeforeTransactionTestCase.class.getSimpleName(),//
|
||||
FailingAfterTransactionTestCase.class.getSimpleName() //
|
||||
};
|
||||
}
|
||||
|
||||
public FailingBeforeAndAfterMethodsJUnitTests(String testClassName) throws Exception {
|
||||
this.clazz = ClassUtils.forName(getClass().getName() + "." + testClassName, getClass().getClassLoader());
|
||||
}
|
||||
|
||||
protected Runner getRunner(Class<?> testClass) throws Exception {
|
||||
Class<? extends Runner> runnerClass = testClass.getAnnotation(RunWith.class).value();
|
||||
Constructor<?> constructor = runnerClass.getConstructor(Class.class);
|
||||
return (Runner) BeanUtils.instantiateClass(constructor, testClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runTestAndAssertCounters() throws Exception {
|
||||
final TrackingRunListener listener = new TrackingRunListener();
|
||||
final RunNotifier notifier = new RunNotifier();
|
||||
TrackingRunListener listener = new TrackingRunListener();
|
||||
RunNotifier notifier = new RunNotifier();
|
||||
notifier.addListener(listener);
|
||||
|
||||
new SpringJUnit4ClassRunner(this.clazz).run(notifier);
|
||||
assertEquals("Verifying number of failures for test class [" + this.clazz + "].", 1,
|
||||
listener.getTestFailureCount());
|
||||
getRunner(this.clazz).run(notifier);
|
||||
assertEquals("Failures for test class [" + this.clazz + "].", 1, listener.getTestFailureCount());
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
static class AlwaysFailingBeforeTestClassTestExecutionListener extends AbstractTestExecutionListener {
|
||||
protected static class AlwaysFailingBeforeTestClassTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(TestContext testContext) {
|
||||
@@ -107,7 +108,7 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class AlwaysFailingAfterTestClassTestExecutionListener extends AbstractTestExecutionListener {
|
||||
protected static class AlwaysFailingAfterTestClassTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void afterTestClass(TestContext testContext) {
|
||||
@@ -115,7 +116,7 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class AlwaysFailingPrepareTestInstanceTestExecutionListener extends AbstractTestExecutionListener {
|
||||
protected static class AlwaysFailingPrepareTestInstanceTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void prepareTestInstance(TestContext testContext) throws Exception {
|
||||
@@ -123,7 +124,7 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class AlwaysFailingBeforeTestMethodTestExecutionListener extends AbstractTestExecutionListener {
|
||||
protected static class AlwaysFailingBeforeTestMethodTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) {
|
||||
@@ -131,7 +132,7 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class AlwaysFailingAfterTestMethodTestExecutionListener extends AbstractTestExecutionListener {
|
||||
protected static class AlwaysFailingAfterTestMethodTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void afterTestMethod(TestContext testContext) {
|
||||
@@ -174,8 +175,10 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("FailingBeforeAndAfterMethodsTests-context.xml")
|
||||
public static class FailingBeforeTransactionTestCase extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
@Transactional
|
||||
public static class FailingBeforeTransactionTestCase {
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
@@ -188,8 +191,10 @@ public class FailingBeforeAndAfterMethodsJUnitTests {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("FailingBeforeAndAfterMethodsTests-context.xml")
|
||||
public static class FailingAfterTransactionTestCase extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
@Transactional
|
||||
public static class FailingAfterTransactionTestCase {
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
@@ -36,7 +34,6 @@ import org.springframework.util.ResourceUtils;
|
||||
* @since 2.5
|
||||
* @see SpringJUnit4ClassRunnerAppCtxTests
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration( { MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.CLASSPATH_RESOURCE_PATH,
|
||||
MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.LOCAL_RESOURCE_PATH,
|
||||
MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.ABSOLUTE_RESOURCE_PATH })
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
@@ -51,15 +48,16 @@ import static org.junit.Assert.*;
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
* @see org.springframework.test.context.junit4.rules.ParameterizedSpringRuleTests
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@ContextConfiguration
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
|
||||
public class ParameterizedDependencyInjectionTests {
|
||||
|
||||
private static final List<Employee> employees = new ArrayList<Employee>();
|
||||
private static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
|
||||
private final TestContextManager testContextManager = new TestContextManager(getClass());
|
||||
private static final TestContextManager testContextManager = new TestContextManager(ParameterizedDependencyInjectionTests.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@@ -75,37 +73,37 @@ public class ParameterizedDependencyInjectionTests {
|
||||
|
||||
|
||||
@Parameters(name = "bean [{0}], employee [{1}]")
|
||||
public static Collection<String[]> employeeData() {
|
||||
return Arrays.asList(new String[][] { { "employee1", "John Smith" }, { "employee2", "Jane Smith" } });
|
||||
public static String[][] employeeData() {
|
||||
return new String[][] { { "employee1", "John Smith" }, { "employee2", "Jane Smith" } };
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void clearEmployees() {
|
||||
employees.clear();
|
||||
public static void BeforeClass() {
|
||||
invocationCount.set(0);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void injectDependencies() throws Throwable {
|
||||
this.testContextManager.prepareTestInstance(this);
|
||||
public void injectDependencies() throws Exception {
|
||||
testContextManager.prepareTestInstance(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyPetAndEmployee() {
|
||||
invocationCount.incrementAndGet();
|
||||
|
||||
// Verifying dependency injection:
|
||||
assertNotNull("The pet field should have been autowired.", this.pet);
|
||||
|
||||
// Verifying 'parameterized' support:
|
||||
final Employee employee = (Employee) this.applicationContext.getBean(this.employeeBeanName);
|
||||
employees.add(employee);
|
||||
assertEquals("Verifying the name of the employee configured as bean [" + this.employeeBeanName + "].",
|
||||
this.employeeName, employee.getName());
|
||||
Employee employee = this.applicationContext.getBean(this.employeeBeanName, Employee.class);
|
||||
assertEquals("Name of the employee configured as bean [" + this.employeeBeanName + "].", this.employeeName,
|
||||
employee.getName());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void verifyNumParameterizedRuns() {
|
||||
assertEquals("Verifying the number of times the parameterized test method was executed.",
|
||||
employeeData().size(), employees.size());
|
||||
assertEquals("Number of times the parameterized test method was executed.", employeeData().length,
|
||||
invocationCount.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.test.context.junit4;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
@@ -30,7 +28,6 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
* @see SpringJUnit4ClassRunnerAppCtxTests
|
||||
* @see AbsolutePathSpringJUnit4ClassRunnerAppCtxTests
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "SpringJUnit4ClassRunnerAppCtxTests-context.xml" })
|
||||
public class RelativePathSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests {
|
||||
/* all tests are in the parent class. */
|
||||
|
||||
@@ -19,13 +19,12 @@ package org.springframework.test.context.junit4;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runner.Runner;
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
@@ -41,8 +40,8 @@ import static org.junit.Assert.*;
|
||||
* Verifies proper handling of the following in conjunction with the
|
||||
* {@link SpringJUnit4ClassRunner}:
|
||||
* <ul>
|
||||
* <li>Spring's {@link Repeat @Repeat}</li>
|
||||
* <li>Spring's {@link Timed @Timed}</li>
|
||||
* <li>Spring's {@link Repeat @Repeat}</li>
|
||||
* <li>Spring's {@link Timed @Timed}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
@@ -51,22 +50,19 @@ import static org.junit.Assert.*;
|
||||
@RunWith(Parameterized.class)
|
||||
public class RepeatedSpringRunnerTests {
|
||||
|
||||
private static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
protected static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
|
||||
private final Class<?> testClass;
|
||||
|
||||
private final int expectedFailureCount;
|
||||
|
||||
private final int expectedTestStartedCount;
|
||||
|
||||
private final int expectedTestFinishedCount;
|
||||
|
||||
private final int expectedInvocationCount;
|
||||
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Collection<Object[]> repetitionData() {
|
||||
return Arrays.asList(new Object[][] {//
|
||||
public static Object[][] repetitionData() {
|
||||
return new Object[][] {//
|
||||
//
|
||||
{ NonAnnotatedRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
|
||||
{ DefaultRepeatValueRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
|
||||
@@ -74,7 +70,7 @@ public class RepeatedSpringRunnerTests {
|
||||
{ RepeatedFiveTimesRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 5 },//
|
||||
{ RepeatedFiveTimesViaMetaAnnotationRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 5 },//
|
||||
{ TimedRepeatedTestCase.class.getSimpleName(), 3, 4, 4, (5 + 1 + 4 + 10) } //
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
public RepeatedSpringRunnerTests(String testClassName, int expectedFailureCount,
|
||||
@@ -86,6 +82,10 @@ public class RepeatedSpringRunnerTests {
|
||||
this.expectedInvocationCount = expectedInvocationCount;
|
||||
}
|
||||
|
||||
protected Runner getRunner(Class<?> testClass) throws Exception {
|
||||
return new SpringJUnit4ClassRunner(testClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertRepetitions() throws Exception {
|
||||
TrackingRunListener listener = new TrackingRunListener();
|
||||
@@ -93,19 +93,14 @@ public class RepeatedSpringRunnerTests {
|
||||
notifier.addListener(listener);
|
||||
invocationCount.set(0);
|
||||
|
||||
new SpringJUnit4ClassRunner(this.testClass).run(notifier);
|
||||
assertEquals("Verifying number of failures for test class [" + this.testClass + "].",
|
||||
this.expectedFailureCount, listener.getTestFailureCount());
|
||||
assertEquals("Verifying number of tests started for test class [" + this.testClass + "].",
|
||||
this.expectedTestStartedCount, listener.getTestStartedCount());
|
||||
assertEquals("Verifying number of tests finished for test class [" + this.testClass + "].",
|
||||
this.expectedTestFinishedCount, listener.getTestFinishedCount());
|
||||
assertEquals("Verifying number of invocations for test class [" + this.testClass + "].",
|
||||
this.expectedInvocationCount, invocationCount.get());
|
||||
getRunner(this.testClass).run(notifier);
|
||||
assertEquals("failures for [" + testClass + "].", expectedFailureCount, listener.getTestFailureCount());
|
||||
assertEquals("tests started for [" + testClass + "].", expectedTestStartedCount, listener.getTestStartedCount());
|
||||
assertEquals("tests finished for [" + testClass + "].", expectedTestFinishedCount, listener.getTestFinishedCount());
|
||||
assertEquals("invocations for [" + testClass + "].", expectedInvocationCount, invocationCount.get());
|
||||
}
|
||||
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@TestExecutionListeners({})
|
||||
public abstract static class AbstractRepeatedTestCase {
|
||||
|
||||
@@ -167,9 +162,7 @@ public class RepeatedSpringRunnerTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for claims raised in <a
|
||||
* href="http://jira.springframework.org/browse/SPR-6011"
|
||||
* target="_blank">SPR-6011</a>.
|
||||
* Unit tests for claims raised in <a href="https://jira.spring.io/browse/SPR-6011" target="_blank">SPR-6011</a>.
|
||||
*/
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
public static final class TimedRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.springframework.test.context.cache.ClassLevelDirtiesContextTests;
|
||||
import org.springframework.test.context.cache.SpringRunnerContextCacheTests;
|
||||
import org.springframework.test.context.jdbc.RequiresNewTransactionSqlScriptsTests;
|
||||
import org.springframework.test.context.junit4.annotation.AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests;
|
||||
import org.springframework.test.context.junit4.annotation.BeanOverridingDefaultConfigClassesInheritedTests;
|
||||
import org.springframework.test.context.junit4.annotation.BeanOverridingExplicitConfigClassesInheritedTests;
|
||||
@@ -41,6 +42,7 @@ import org.springframework.test.context.junit4.profile.annotation.DevProfileReso
|
||||
import org.springframework.test.context.junit4.profile.xml.DefaultProfileXmlConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.xml.DevProfileResolverXmlConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.xml.DevProfileXmlConfigTests;
|
||||
import org.springframework.test.context.transaction.programmatic.ProgrammaticTxMgmtTests;
|
||||
|
||||
/**
|
||||
* JUnit test suite for tests involving {@link SpringJUnit4ClassRunner} and the
|
||||
@@ -99,6 +101,7 @@ StandardJUnit4FeaturesTests.class,//
|
||||
SpringRunnerContextCacheTests.class,//
|
||||
ClassLevelDirtiesContextTests.class,//
|
||||
ParameterizedDependencyInjectionTests.class,//
|
||||
ConcreteTransactionalJUnit4SpringContextTests.class,//
|
||||
ClassLevelTransactionalSpringRunnerTests.class,//
|
||||
MethodLevelTransactionalSpringRunnerTests.class,//
|
||||
DefaultRollbackTrueTransactionalSpringRunnerTests.class,//
|
||||
@@ -107,6 +110,8 @@ StandardJUnit4FeaturesTests.class,//
|
||||
RollbackOverrideDefaultRollbackFalseTransactionalSpringRunnerTests.class,//
|
||||
BeforeAndAfterTransactionAnnotationTests.class,//
|
||||
TimedTransactionalSpringRunnerTests.class,//
|
||||
ProgrammaticTxMgmtTests.class,//
|
||||
RequiresNewTransactionSqlScriptsTests.class,//
|
||||
HibernateSessionFlushingTests.class //
|
||||
})
|
||||
public class SpringJUnit4TestSuite {
|
||||
|
||||
@@ -22,13 +22,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runner.Runner;
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.annotation.Timed;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.tests.Assume;
|
||||
import org.springframework.tests.TestGroup;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -46,32 +45,33 @@ import static org.junit.Assert.*;
|
||||
@RunWith(JUnit4.class)
|
||||
public class TimedSpringRunnerTests {
|
||||
|
||||
protected Class<?> getTestCase() {
|
||||
return TimedSpringRunnerTestCase.class;
|
||||
}
|
||||
|
||||
protected Runner getRunner(Class<?> testClass) throws Exception {
|
||||
return new SpringJUnit4ClassRunner(testClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timedTests() throws Exception {
|
||||
Assume.group(TestGroup.PERFORMANCE);
|
||||
Class<TimedSpringRunnerTestCase> testClass = TimedSpringRunnerTestCase.class;
|
||||
Class<?> testClass = getTestCase();
|
||||
TrackingRunListener listener = new TrackingRunListener();
|
||||
RunNotifier notifier = new RunNotifier();
|
||||
notifier.addListener(listener);
|
||||
|
||||
new SpringJUnit4ClassRunner(testClass).run(notifier);
|
||||
assertEquals("Verifying number of tests started for test class [" + testClass + "].", 7,
|
||||
listener.getTestStartedCount());
|
||||
assertEquals("Verifying number of tests ignored for test class [" + testClass + "].", 0,
|
||||
listener.getTestIgnoredCount());
|
||||
assertEquals("Verifying number of assumption failures for test class [" + testClass + "].", 0,
|
||||
listener.getTestAssumptionFailureCount());
|
||||
assertEquals("Verifying number of test failures for test class [" + testClass + "].", 5,
|
||||
listener.getTestFailureCount());
|
||||
assertEquals("Verifying number of tests finished for test class [" + testClass + "].", 7,
|
||||
listener.getTestFinishedCount());
|
||||
getRunner(testClass).run(notifier);
|
||||
assertEquals("tests started for [" + testClass + "].", 7, listener.getTestStartedCount());
|
||||
assertEquals("tests ignored for [" + testClass + "].", 0, listener.getTestIgnoredCount());
|
||||
assertEquals("assumption failures for [" + testClass + "].", 0, listener.getTestAssumptionFailureCount());
|
||||
assertEquals("test failures for [" + testClass + "].", 5, listener.getTestFailureCount());
|
||||
assertEquals("tests finished for [" + testClass + "].", 7, listener.getTestFinishedCount());
|
||||
}
|
||||
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@TestExecutionListeners({})
|
||||
public static final class TimedSpringRunnerTestCase {
|
||||
public static class TimedSpringRunnerTestCase {
|
||||
|
||||
// Should Pass.
|
||||
@Test(timeout = 2000)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Base class for integration tests involving Spring {@code ApplicationContexts}
|
||||
* in conjunction with {@link SpringClassRule} and {@link SpringMethodRule}.
|
||||
*
|
||||
* <p>The goal of this class and its subclasses is to ensure that Rule-based
|
||||
* configuration can be inherited without requiring {@link SpringClassRule}
|
||||
* or {@link SpringMethodRule} to be redeclared on subclasses.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
* @see Subclass1AppCtxRuleTests
|
||||
* @see Subclass2AppCtxRuleTests
|
||||
*/
|
||||
@ContextConfiguration
|
||||
public class BaseAppCtxRuleTests {
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
@Autowired
|
||||
String foo;
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertEquals("foo", foo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.context.web.BasicAnnotationConfigWacTests;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link BasicAnnotationConfigWacTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class BasicAnnotationConfigWacSpringRuleTests extends BasicAnnotationConfigWacTests {
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.context.junit4.BeforeAndAfterTransactionAnnotationTests;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link BeforeAndAfterTransactionAnnotationTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class BeforeAndAfterTransactionAnnotationSpringRuleTests extends BeforeAndAfterTransactionAnnotationTests {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.context.junit4.ClassLevelDisabledSpringRunnerTests;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link ClassLevelDisabledSpringRunnerTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class ClassLevelDisabledSpringRuleTests extends ClassLevelDisabledSpringRunnerTests {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.context.junit4.EnabledAndIgnoredSpringRunnerTests;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link EnabledAndIgnoredSpringRunnerTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class EnabledAndIgnoredSpringRuleTests extends EnabledAndIgnoredSpringRunnerTests {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.FailingBeforeAndAfterMethodsJUnitTests;
|
||||
import org.springframework.test.context.transaction.AfterTransaction;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link FailingBeforeAndAfterMethodsJUnitTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
public class FailingBeforeAndAfterMethodsSpringRuleTests extends FailingBeforeAndAfterMethodsJUnitTests {
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Object[] testData() {
|
||||
return new Object[] {//
|
||||
AlwaysFailingBeforeTestClassSpringRuleTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingAfterTestClassSpringRuleTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingPrepareTestInstanceSpringRuleTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingBeforeTestMethodSpringRuleTestCase.class.getSimpleName(),//
|
||||
AlwaysFailingAfterTestMethodSpringRuleTestCase.class.getSimpleName(),//
|
||||
FailingBeforeTransactionSpringRuleTestCase.class.getSimpleName(),//
|
||||
FailingAfterTransactionSpringRuleTestCase.class.getSimpleName() //
|
||||
};
|
||||
}
|
||||
|
||||
public FailingBeforeAndAfterMethodsSpringRuleTests(String testClassName) throws Exception {
|
||||
super(testClassName);
|
||||
}
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
@TestExecutionListeners({})
|
||||
public static abstract class BaseSpringRuleTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@TestExecutionListeners(AlwaysFailingBeforeTestClassTestExecutionListener.class)
|
||||
public static class AlwaysFailingBeforeTestClassSpringRuleTestCase extends BaseSpringRuleTestCase {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@TestExecutionListeners(AlwaysFailingAfterTestClassTestExecutionListener.class)
|
||||
public static class AlwaysFailingAfterTestClassSpringRuleTestCase extends BaseSpringRuleTestCase {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@TestExecutionListeners(AlwaysFailingPrepareTestInstanceTestExecutionListener.class)
|
||||
public static class AlwaysFailingPrepareTestInstanceSpringRuleTestCase extends BaseSpringRuleTestCase {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@TestExecutionListeners(AlwaysFailingBeforeTestMethodTestExecutionListener.class)
|
||||
public static class AlwaysFailingBeforeTestMethodSpringRuleTestCase extends BaseSpringRuleTestCase {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@TestExecutionListeners(AlwaysFailingAfterTestMethodTestExecutionListener.class)
|
||||
public static class AlwaysFailingAfterTestMethodSpringRuleTestCase extends BaseSpringRuleTestCase {
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@RunWith(JUnit4.class)
|
||||
@ContextConfiguration("../FailingBeforeAndAfterMethodsTests-context.xml")
|
||||
@Transactional
|
||||
public static class FailingBeforeTransactionSpringRuleTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
}
|
||||
|
||||
@BeforeTransaction
|
||||
public void beforeTransaction() {
|
||||
fail("always failing beforeTransaction()");
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@RunWith(JUnit4.class)
|
||||
@ContextConfiguration("../FailingBeforeAndAfterMethodsTests-context.xml")
|
||||
@Transactional
|
||||
public static class FailingAfterTransactionSpringRuleTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
}
|
||||
|
||||
@AfterTransaction
|
||||
public void afterTransaction() {
|
||||
fail("always failing afterTransaction()");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Integration test which demonstrates how to use JUnit's {@link Parameterized}
|
||||
* runner in conjunction with {@link SpringClassRule} and {@link SpringMethodRule}
|
||||
* to provide dependency injection to a <em>parameterized test instance</em>.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
* @see org.springframework.test.context.junit4.ParameterizedDependencyInjectionTests
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@ContextConfiguration("/org/springframework/test/context/junit4/ParameterizedDependencyInjectionTests-context.xml")
|
||||
public class ParameterizedSpringRuleTests {
|
||||
|
||||
private static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private Pet pet;
|
||||
|
||||
@Parameter(0)
|
||||
public String employeeBeanName;
|
||||
|
||||
@Parameter(1)
|
||||
public String employeeName;
|
||||
|
||||
|
||||
@Parameters(name = "bean [{0}], employee [{1}]")
|
||||
public static String[][] employeeData() {
|
||||
return new String[][] { { "employee1", "John Smith" }, { "employee2", "Jane Smith" } };
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void BeforeClass() {
|
||||
invocationCount.set(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyPetAndEmployee() {
|
||||
invocationCount.incrementAndGet();
|
||||
|
||||
// Verifying dependency injection:
|
||||
assertNotNull("The pet field should have been autowired.", this.pet);
|
||||
|
||||
// Verifying 'parameterized' support:
|
||||
Employee employee = this.applicationContext.getBean(this.employeeBeanName, Employee.class);
|
||||
assertEquals("Name of the employee configured as bean [" + this.employeeBeanName + "].", this.employeeName,
|
||||
employee.getName());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void verifyNumParameterizedRuns() {
|
||||
assertEquals("Number of times the parameterized test method was executed.", employeeData().length,
|
||||
invocationCount.get());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.transaction.programmatic.ProgrammaticTxMgmtTests;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link ProgrammaticTxMgmtTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
@ContextConfiguration
|
||||
public class ProgrammaticTxMgmtSpringRuleTests extends ProgrammaticTxMgmtTests {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
return new DataSourceTransactionManager(dataSource());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder()//
|
||||
.generateUniqueName(true)//
|
||||
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql") //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.Runner;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.annotation.Timed;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.RepeatedSpringRunnerTests;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link RepeatedSpringRunnerTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
public class RepeatedSpringRuleTests extends RepeatedSpringRunnerTests {
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Object[][] repetitionData() {
|
||||
return new Object[][] {//
|
||||
//
|
||||
{ NonAnnotatedRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
|
||||
{ DefaultRepeatValueRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
|
||||
{ NegativeRepeatValueRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
|
||||
{ RepeatedFiveTimesRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 5 },//
|
||||
{ RepeatedFiveTimesViaMetaAnnotationRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 5 },//
|
||||
{ TimedRepeatedTestCase.class.getSimpleName(), 3, 4, 4, (5 + 1 + 4 + 10) } //
|
||||
};
|
||||
}
|
||||
|
||||
public RepeatedSpringRuleTests(String testClassName, int expectedFailureCount, int expectedTestStartedCount,
|
||||
int expectedTestFinishedCount, int expectedInvocationCount) throws Exception {
|
||||
|
||||
super(testClassName, expectedFailureCount, expectedTestStartedCount, expectedTestFinishedCount,
|
||||
expectedInvocationCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Runner getRunner(Class<?> testClass) throws Exception {
|
||||
return new JUnit4(testClass);
|
||||
}
|
||||
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
@TestExecutionListeners({})
|
||||
public abstract static class AbstractRepeatedTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
|
||||
protected void incrementInvocationCount() throws IOException {
|
||||
invocationCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class NonAnnotatedRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@Test
|
||||
@Timed(millis = 10000)
|
||||
public void nonAnnotated() throws Exception {
|
||||
incrementInvocationCount();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class DefaultRepeatValueRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@Test
|
||||
@Repeat
|
||||
@Timed(millis = 10000)
|
||||
public void defaultRepeatValue() throws Exception {
|
||||
incrementInvocationCount();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class NegativeRepeatValueRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@Test
|
||||
@Repeat(-5)
|
||||
@Timed(millis = 10000)
|
||||
public void negativeRepeatValue() throws Exception {
|
||||
incrementInvocationCount();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class RepeatedFiveTimesRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@Test
|
||||
@Repeat(5)
|
||||
public void repeatedFiveTimes() throws Exception {
|
||||
incrementInvocationCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Repeat(5)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
private static @interface RepeatedFiveTimes {
|
||||
}
|
||||
|
||||
public static final class RepeatedFiveTimesViaMetaAnnotationRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@Test
|
||||
@RepeatedFiveTimes
|
||||
public void repeatedFiveTimes() throws Exception {
|
||||
incrementInvocationCount();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for claims raised in <a href="https://jira.spring.io/browse/SPR-6011" target="_blank">SPR-6011</a>.
|
||||
*/
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
public static final class TimedRepeatedTestCase extends AbstractRepeatedTestCase {
|
||||
|
||||
@Test
|
||||
@Timed(millis = 1000)
|
||||
@Repeat(5)
|
||||
public void repeatedFiveTimesButDoesNotExceedTimeout() throws Exception {
|
||||
incrementInvocationCount();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timed(millis = 10)
|
||||
@Repeat(1)
|
||||
public void singleRepetitionExceedsTimeout() throws Exception {
|
||||
incrementInvocationCount();
|
||||
Thread.sleep(15);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timed(millis = 20)
|
||||
@Repeat(4)
|
||||
public void firstRepetitionOfManyExceedsTimeout() throws Exception {
|
||||
incrementInvocationCount();
|
||||
Thread.sleep(25);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timed(millis = 100)
|
||||
@Repeat(10)
|
||||
public void collectiveRepetitionsExceedTimeout() throws Exception {
|
||||
incrementInvocationCount();
|
||||
Thread.sleep(11);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
/**
|
||||
* Subclass #1 of {@link BaseAppCtxRuleTests}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
public class Subclass1AppCtxRuleTests extends BaseAppCtxRuleTests {
|
||||
|
||||
// All tests and config are in superclass.
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
/**
|
||||
* Subclass #2 of {@link BaseAppCtxRuleTests}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
public class Subclass2AppCtxRuleTests extends BaseAppCtxRuleTests {
|
||||
|
||||
// All tests and config are in superclass.
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.Runner;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.TimedSpringRunnerTests;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link TimedSpringRunnerTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
public class TimedSpringRuleTests extends TimedSpringRunnerTests {
|
||||
|
||||
// All tests are in superclass.
|
||||
|
||||
@Override
|
||||
protected Class<?> getTestCase() {
|
||||
return TimedSpringRuleTestCase.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Runner getRunner(Class<?> testClass) throws Exception {
|
||||
return new JUnit4(testClass);
|
||||
}
|
||||
|
||||
|
||||
@Ignore("TestCase classes are run manually by the enclosing test class")
|
||||
@TestExecutionListeners({})
|
||||
public static final class TimedSpringRuleTestCase extends TimedSpringRunnerTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
|
||||
/**
|
||||
* Overridden to always throw an exception, since Spring's Rule-based
|
||||
* JUnit integration does not fail a test for duplicate configuration
|
||||
* of timeouts.
|
||||
*/
|
||||
@Override
|
||||
public void springAndJUnitTimeouts() {
|
||||
fail("intentional failure to make tests in superclass pass");
|
||||
}
|
||||
|
||||
// All other tests are in superclass.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.context.junit4.TimedTransactionalSpringRunnerTests;
|
||||
|
||||
import static org.springframework.test.transaction.TransactionTestUtils.*;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link TimedTransactionalSpringRunnerTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class TimedTransactionalSpringRuleTests extends TimedTransactionalSpringRunnerTests {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
@Rule
|
||||
public Timeout timeout = Timeout.builder().withTimeout(10, TimeUnit.SECONDS).build();
|
||||
|
||||
|
||||
/**
|
||||
* Overridden since Spring's Rule-based JUnit support cannot properly
|
||||
* integrate with timed execution that is controlled by a third-party runner.
|
||||
*/
|
||||
@Test(timeout = 10000)
|
||||
@Repeat(5)
|
||||
@Override
|
||||
public void transactionalWithJUnitTimeout() {
|
||||
assertInTransaction(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code timeout} explicitly not declared due to presence of Timeout rule.
|
||||
*/
|
||||
@Test
|
||||
public void transactionalWithJUnitRuleBasedTimeout() {
|
||||
assertInTransaction(true);
|
||||
}
|
||||
|
||||
// All other tests are in superclass.
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.junit4.rules;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.TransactionalSqlScriptsTests;
|
||||
|
||||
/**
|
||||
* This class is an extension of {@link TransactionalSqlScriptsTests}
|
||||
* that has been modified to use {@link SpringClassRule} and
|
||||
* {@link SpringMethodRule}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
// Note: @FixMethodOrder is NOT @Inherited.
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
// Overriding @Sql declaration to reference scripts using relative path.
|
||||
@Sql({ "../../jdbc/schema.sql", "../../jdbc/data.sql" })
|
||||
public class TransactionalSqlScriptsSpringRuleTests extends TransactionalSqlScriptsTests {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
|
||||
|
||||
@Rule
|
||||
public Timeout timeout = Timeout.builder().withTimeout(10, TimeUnit.SECONDS).build();
|
||||
|
||||
|
||||
/**
|
||||
* Redeclared to ensure that {@code @FixMethodOrder} is properly applied.
|
||||
*/
|
||||
@Test
|
||||
@Override
|
||||
// test##_ prefix is required for @FixMethodOrder.
|
||||
public void test01_classLevelScripts() {
|
||||
assertNumUsers(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriding {@code @Sql} declaration to reference scripts using relative path.
|
||||
*/
|
||||
@Test
|
||||
@Sql({ "../../jdbc/drop-schema.sql", "../../jdbc/schema.sql", "../../jdbc/data.sql", "../../jdbc/data-add-dogbert.sql" })
|
||||
@Override
|
||||
// test##_ prefix is required for @FixMethodOrder.
|
||||
public void test02_methodLevelScripts() {
|
||||
assertNumUsers(2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -25,16 +25,25 @@ import javax.sql.DataSource;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.transaction.AfterTransaction;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
import org.springframework.test.context.transaction.TestTransaction;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -49,13 +58,28 @@ import static org.springframework.test.transaction.TransactionTestUtils.*;
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class ProgrammaticTxMgmtTests extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
@Transactional
|
||||
public class ProgrammaticTxMgmtTests {
|
||||
|
||||
private String sqlScriptEncoding;
|
||||
|
||||
protected JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
@Rule
|
||||
public TestName testName = new TestName();
|
||||
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
|
||||
@BeforeTransaction
|
||||
public void beforeTransaction() {
|
||||
deleteFromTables("user");
|
||||
@@ -242,6 +266,15 @@ public class ProgrammaticTxMgmtTests extends AbstractTransactionalJUnit4SpringCo
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected int deleteFromTables(String... names) {
|
||||
return JdbcTestUtils.deleteFromTables(this.jdbcTemplate, names);
|
||||
}
|
||||
|
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||
new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(jdbcTemplate.getDataSource());
|
||||
}
|
||||
|
||||
private void assertUsers(String... users) {
|
||||
List<String> expected = Arrays.asList(users);
|
||||
Collections.sort(expected);
|
||||
@@ -250,7 +283,6 @@ public class ProgrammaticTxMgmtTests extends AbstractTransactionalJUnit4SpringCo
|
||||
assertEquals("Users in database;", expected, actual);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Configuration
|
||||
@@ -264,7 +296,7 @@ public class ProgrammaticTxMgmtTests extends AbstractTransactionalJUnit4SpringCo
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder()//
|
||||
.setName("programmatic-tx-mgmt-test-db")//
|
||||
.generateUniqueName(true)//
|
||||
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql") //
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -10,13 +10,17 @@ log4j.appender.file.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%c] - %m%n
|
||||
log4j.rootCategory=ERROR, console, file
|
||||
|
||||
log4j.logger.org.springframework.beans=WARN
|
||||
|
||||
log4j.logger.org.springframework.test.context.TestContext=WARN
|
||||
log4j.logger.org.springframework.test.context.TestContextManager=WARN
|
||||
log4j.logger.org.springframework.test.context.ContextLoaderUtils=WARN
|
||||
log4j.logger.org.springframework.test.context.transaction.TransactionalTestExecutionListener=WARN
|
||||
log4j.logger.org.springframework.test.context.web=WARN
|
||||
log4j.logger.org.springframework.test.context=WARN
|
||||
log4j.logger.org.springframework.test.context.cache=WARN
|
||||
|
||||
log4j.logger.org.springframework.test.context.junit4.rules=WARN
|
||||
|
||||
#log4j.logger.org.springframework.test.context.support=INFO
|
||||
#log4j.logger.org.springframework.test.context.support.DelegatingSmartContextLoader=INFO
|
||||
#log4j.logger.org.springframework.test.context.support.AbstractGenericContextLoader=INFO
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="employee1" class="org.springframework.tests.sample.beans.Employee">
|
||||
<property name="name" value="John Smith" />
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
|
||||
p:driverClassName="org.hsqldb.jdbcDriver" p:url="jdbc:hsqldb:mem:transactional_tests" p:username="sa" p:password=""/>
|
||||
|
||||
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
|
||||
p:driverClassName="org.hsqldb.jdbcDriver" p:url="jdbc:hsqldb:mem:transactional_tests" p:username="sa" p:password=""/>
|
||||
<jdbc:embedded-database id="dataSource" generate-name="true" type="HSQL" />
|
||||
<jdbc:embedded-database id="dataSource2" generate-name="true" type="HSQL" />
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
|
||||
p:dataSource-ref="dataSource"/>
|
||||
p:dataSource-ref="dataSource" />
|
||||
|
||||
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
|
||||
p:dataSource-ref="dataSource2">
|
||||
|
||||
Reference in New Issue
Block a user