提交 439b6406 编写于 作者: S Sam Brannen

Merge from sbrannen/SPR-7731

* SPR-7731:
  Introduce JUnit Rule alternative to SpringJUnit4ClassRunner
/*
* 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 &#064;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 &#064;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
* &#064;ContextConfiguration}, {@link TestExecutionListeners
* &#064;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.
*
......
/*
* 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
* &#064;ContextConfiguration}, {@link TestExecutionListeners
* &#064;TestExecutionListeners}, {@link Transactional &#064;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
*/
......
/*
* 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 {
*
* &#064;ClassRule
* public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
*
* &#064;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));
}
}
}
/*
* 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 {
*
* &#064;ClassRule
* public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
*
* &#064;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} &mdash; for example:
*
* <pre><code> &#064;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);
}
}
/**
* Custom JUnit {@code Rules} used in the <em>Spring TestContext Framework</em>.
*/
package org.springframework.test.context.junit4.rules;
/*
* 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
* &#064;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
......
/*
* 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 {
......
/*
* 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. */
......
/*
* 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 &#064;BeforeTransaction} and
* {@link AfterTransaction &#064;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() {
......
/*
* 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 &#064;Repeat}</li>
* <li>Spring's {@link Timed &#064;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)
......
/*
* 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);
}
}
/*
* 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);
}
/*
* 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.
}
/*
* 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.
}
/*
* 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.
}
/*
* 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()");
}
}
}
/*
* 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());
}
}
/*
* 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();
}
}
}
/*
* 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);
}
}
}
/*
* 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.
}
/*
* 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.
}
/*
* 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.
}
}
/*
* 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.
}
/*
* 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);
}
}
/*
* 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
......
<?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" />
......
<?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">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册