提交 b4e16eac 编写于 作者: S Sam Brannen

Require JUnit 4.9 or higher in the TCF

Prior to this commit, the Spring TestContext Framework (TCF) was
compatible with JUnit 4.5 or higher.

This commit effectively raises the minimum version of JUnit that is
officially supported by the TCF to JUnit 4.9, thereby aligning with
similar upgrades made in the Spring Framework 4.0 release (i.e.,
upgrading minimum requirements on third-party libraries to versions
released mid 2010 or later).

Issue: SPR-11908
上级 2d892da6
......@@ -34,7 +34,7 @@ import org.springframework.test.context.web.ServletTestExecutionListener;
/**
* Abstract base test class which integrates the <em>Spring TestContext
* Framework</em> with explicit {@link ApplicationContext} testing support in a
* <strong>JUnit 4.5+</strong> environment.
* <strong>JUnit 4.9+</strong> environment.
*
* <p>Concrete subclasses should typically declare a class-level
* {@link ContextConfiguration &#064;ContextConfiguration} annotation to
......
......@@ -22,8 +22,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.internal.AssumptionViolatedException;
import org.junit.internal.runners.model.EachTestNotifier;
import org.junit.internal.runners.model.ReflectiveCallable;
import org.junit.internal.runners.statements.ExpectException;
import org.junit.internal.runners.statements.Fail;
......@@ -50,18 +48,17 @@ import org.springframework.test.context.junit4.statements.SpringRepeat;
import org.springframework.util.ReflectionUtils;
/**
* <p>{@code SpringJUnit4ClassRunner} is a custom extension of JUnit's
* {@code SpringJUnit4ClassRunner} is a custom extension of JUnit's
* {@link BlockJUnit4ClassRunner} which provides functionality of the
* <em>Spring TestContext Framework</em> to standard JUnit 4.5+ tests by means
* of the {@link TestContextManager} and associated support classes and
* annotations.
* <em>Spring TestContext Framework</em> to standard JUnit tests by means of the
* {@link TestContextManager} and associated support classes and annotations.
*
* <p>The following list constitutes all annotations currently supported directly
* or indirectly by {@code SpringJUnit4ClassRunner}.
* <em>(Note that additional annotations may be supported by various {@link
* org.springframework.test.context.TestExecutionListener TestExecutionListeners}
* or {@link org.springframework.test.context.TestContextBootstrapper
* TestContextBootstrapper} implementations.)</em>
* or indirectly by {@code SpringJUnit4ClassRunner}. <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 Test#expected() @Test(expected=...)}</li>
......@@ -73,8 +70,8 @@ import org.springframework.util.ReflectionUtils;
* <li>{@link org.springframework.test.annotation.IfProfileValue @IfProfileValue}</li>
* </ul>
*
* <p><strong>NOTE:</strong> As of Spring 3.0, {@code SpringJUnit4ClassRunner}
* requires JUnit 4.5 or higher.
* <p><strong>NOTE:</strong> As of Spring 4.1, {@code SpringJUnit4ClassRunner}
* requires JUnit 4.9 or higher.
*
* @author Sam Brannen
* @author Juergen Hoeller
......@@ -86,6 +83,18 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
private static final Log logger = LogFactory.getLog(SpringJUnit4ClassRunner.class);
private static final Method withRulesMethod;
static {
withRulesMethod = ReflectionUtils.findMethod(SpringJUnit4ClassRunner.class, "withRules", FrameworkMethod.class,
Object.class, Statement.class);
if (withRulesMethod == null) {
throw new IllegalStateException(
"Failed to find withRules() method: SpringJUnit4ClassRunner requires JUnit 4.9 or higher.");
}
ReflectionUtils.makeAccessible(withRulesMethod);
}
private final TestContextManager testContextManager;
......@@ -198,40 +207,15 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
*/
@Override
protected void runChild(FrameworkMethod frameworkMethod, RunNotifier notifier) {
EachTestNotifier eachNotifier = springMakeNotifier(frameworkMethod, notifier);
Description description = describeChild(frameworkMethod);
if (isTestMethodIgnored(frameworkMethod)) {
eachNotifier.fireTestIgnored();
return;
}
eachNotifier.fireTestStarted();
try {
methodBlock(frameworkMethod).evaluate();
}
catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
}
catch (Throwable e) {
eachNotifier.addFailure(e);
notifier.fireTestIgnored(description);
}
finally {
eachNotifier.fireTestFinished();
else {
runLeaf(methodBlock(frameworkMethod), description, notifier);
}
}
/**
* {@code springMakeNotifier()} is an exact copy of
* {@link BlockJUnit4ClassRunner BlockJUnit4ClassRunner's}
* {@code makeNotifier()} method, but we have decided to prefix it with
* "spring" and keep it {@code private} in order to avoid the
* compatibility clashes that were introduced in JUnit between versions 4.5,
* 4.6, and 4.7.
*/
private EachTestNotifier springMakeNotifier(FrameworkMethod method, RunNotifier notifier) {
Description description = describeChild(method);
return new EachTestNotifier(notifier, description);
}
/**
* Augments the default JUnit behavior
* {@link #withPotentialRepeat(FrameworkMethod, Object, Statement) with
......@@ -252,8 +236,8 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* @see #possiblyExpectingExceptions(FrameworkMethod, Object, Statement)
* @see #withBefores(FrameworkMethod, Object, Statement)
* @see #withAfters(FrameworkMethod, Object, Statement)
* @see #withPotentialTimeout(FrameworkMethod, Object, Statement)
* @see #withPotentialRepeat(FrameworkMethod, Object, Statement)
* @see #withPotentialTimeout(FrameworkMethod, Object, Statement)
*/
@Override
protected Statement methodBlock(FrameworkMethod frameworkMethod) {
......@@ -283,21 +267,10 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
}
/**
* Invokes JUnit 4.7's private {@code withRules()} method using reflection.
* <p>This is necessary for backwards compatibility with the JUnit 4.5 and
* 4.6 implementations of {@link BlockJUnit4ClassRunner}.
* Invoke JUnit's private {@code withRules()} method using reflection.
*/
private Statement withRulesReflectively(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
Method withRulesMethod = ReflectionUtils.findMethod(getClass(), "withRules", FrameworkMethod.class,
Object.class, Statement.class);
if (withRulesMethod != null) {
// Original JUnit 4.7 code:
// statement = withRules(frameworkMethod, testInstance, statement);
ReflectionUtils.makeAccessible(withRulesMethod);
statement = (Statement) ReflectionUtils.invokeMethod(withRulesMethod, this, frameworkMethod, testInstance,
statement);
}
return statement;
return (Statement) ReflectionUtils.invokeMethod(withRulesMethod, this, frameworkMethod, testInstance, statement);
}
/**
......
/**
* <p>Support classes for ApplicationContext-based and transactional
* tests run with JUnit 4.5+ and the <em>Spring TestContext Framework</em>.</p>
* <p>Support classes for integrating the <em>Spring TestContext Framework</em>
* with JUnit.</p>
*/
package org.springframework.test.context.junit4;
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
......@@ -24,10 +24,9 @@ import org.junit.runners.model.Statement;
import org.springframework.test.context.TestContextManager;
/**
* {@code RunAfterTestClassCallbacks} is a custom JUnit 4.5+
* {@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}.
*
* @see #evaluate()
......@@ -35,7 +34,6 @@ import org.springframework.test.context.TestContextManager;
* @author Sam Brannen
* @since 3.0
*/
@SuppressWarnings("deprecation")
public class RunAfterTestClassCallbacks extends Statement {
private final Statement next;
......@@ -56,13 +54,11 @@ public class RunAfterTestClassCallbacks extends Statement {
}
/**
* Invokes the next {@link Statement} in the execution chain (typically an
* instance of {@link org.junit.internal.runners.statements.RunAfters
* RunAfters}), catching any exceptions thrown, and then calls
* {@link TestContextManager#afterTestClass()}. If the call to
* {@code afterTestClass()} throws an exception, it will also be
* tracked. Multiple exceptions will be combined into a
* {@link MultipleFailureException}.
* Invokes the next {@link Statement} in the execution chain (typically an instance of
* {@link org.junit.internal.runners.statements.RunAfters RunAfters}), catching any
* exceptions thrown, and then calls {@link TestContextManager#afterTestClass()}. If
* the call to {@code afterTestClass()} throws an exception, it will also be tracked.
* Multiple exceptions will be combined into a {@link MultipleFailureException}.
*/
@Override
public void evaluate() throws Throwable {
......@@ -87,6 +83,7 @@ public class RunAfterTestClassCallbacks extends Statement {
if (errors.size() == 1) {
throw errors.get(0);
}
throw new org.junit.internal.runners.model.MultipleFailureException(errors);
throw new MultipleFailureException(errors);
}
}
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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,18 +25,16 @@ import org.junit.runners.model.Statement;
import org.springframework.test.context.TestContextManager;
/**
* {@code RunAfterTestMethodCallbacks} is a custom JUnit 4.5+
* {@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}.
* {@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}.
*
* @see #evaluate()
* @see RunBeforeTestMethodCallbacks
* @author Sam Brannen
* @since 3.0
*/
@SuppressWarnings("deprecation")
public class RunAfterTestMethodCallbacks extends Statement {
private final Statement next;
......@@ -67,13 +65,13 @@ public class RunAfterTestMethodCallbacks extends Statement {
}
/**
* Invokes the next {@link Statement} in the execution chain (typically an
* instance of {@link org.junit.internal.runners.statements.RunAfters
* RunAfters}), catching any exceptions thrown, and then calls
* {@link TestContextManager#afterTestMethod(Object, Method, Throwable)} with the first
* caught exception (if any). If the call to {@code afterTestMethod()}
* throws an exception, it will also be tracked. Multiple exceptions will be
* combined into a {@link MultipleFailureException}.
* Invokes the next {@link Statement} in the execution chain (typically an instance of
* {@link org.junit.internal.runners.statements.RunAfters RunAfters}), catching any
* exceptions thrown, and then calls
* {@link TestContextManager#afterTestMethod(Object, Method, Throwable)} with the
* first caught exception (if any). If the call to {@code afterTestMethod()} throws an
* exception, it will also be tracked. Multiple exceptions will be combined into a
* {@link MultipleFailureException}.
*/
@Override
public void evaluate() throws Throwable {
......@@ -100,6 +98,7 @@ public class RunAfterTestMethodCallbacks extends Statement {
if (errors.size() == 1) {
throw errors.get(0);
}
throw new org.junit.internal.runners.model.MultipleFailureException(errors);
throw new MultipleFailureException(errors);
}
}
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -20,10 +20,9 @@ import org.junit.runners.model.Statement;
import org.springframework.test.context.TestContextManager;
/**
* {@code RunBeforeTestClassCallbacks} is a custom JUnit 4.5+
* {@link Statement} which allows the <em>Spring TestContext Framework</em> to
* be plugged into the JUnit execution chain by calling
* {@link TestContextManager#beforeTestClass() beforeTestClass()} on the
* {@code RunBeforeTestClassCallbacks} 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#beforeTestClass() beforeTestClass()} on the
* supplied {@link TestContextManager}.
*
* @see #evaluate()
......@@ -51,8 +50,8 @@ public class RunBeforeTestClassCallbacks extends Statement {
}
/**
* Calls {@link TestContextManager#beforeTestClass()} and then invokes the
* next {@link Statement} in the execution chain (typically an instance of
* Calls {@link TestContextManager#beforeTestClass()} and then invokes the next
* {@link Statement} in the execution chain (typically an instance of
* {@link org.junit.internal.runners.statements.RunBefores RunBefores}).
*/
@Override
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
......@@ -22,10 +22,9 @@ import org.junit.runners.model.Statement;
import org.springframework.test.context.TestContextManager;
/**
* {@code RunBeforeTestMethodCallbacks} is a custom JUnit 4.5+
* {@link Statement} which allows the <em>Spring TestContext Framework</em> to
* be plugged into the JUnit execution chain by calling
* {@link TestContextManager#beforeTestMethod(Object, Method)
* {@code RunBeforeTestMethodCallbacks} 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#beforeTestMethod(Object, Method)
* beforeTestMethod()} on the supplied {@link TestContextManager}.
*
* @see #evaluate()
......@@ -63,10 +62,9 @@ public class RunBeforeTestMethodCallbacks extends Statement {
}
/**
* Calls {@link TestContextManager#beforeTestMethod(Object, Method)} and
* then invokes the next {@link Statement} in the execution chain (typically
* an instance of {@link org.junit.internal.runners.statements.RunBefores
* RunBefores}).
* Calls {@link TestContextManager#beforeTestMethod(Object, Method)} and then invokes
* the next {@link Statement} in the execution chain (typically an instance of
* {@link org.junit.internal.runners.statements.RunBefores RunBefores}).
*/
@Override
public void evaluate() throws Throwable {
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
......@@ -22,10 +22,10 @@ import org.junit.runners.model.Statement;
import org.springframework.test.annotation.Timed;
/**
* {@code SpringFailOnTimeout} is a custom JUnit 4.5+ {@link Statement}
* which adds support for Spring's {@link Timed @Timed} annotation by throwing
* an exception if the next statement in the execution chain takes more than the
* specified number of milliseconds.
* {@code SpringFailOnTimeout} is a custom JUnit {@link Statement} which adds
* support for Spring's {@link Timed @Timed} annotation by throwing an exception
* if the next statement in the execution chain takes more than the specified
* number of milliseconds.
*
* @see #evaluate()
* @author Sam Brannen
......@@ -55,9 +55,8 @@ public class SpringFailOnTimeout extends Statement {
* (typically an instance of
* {@link org.junit.internal.runners.statements.InvokeMethod InvokeMethod}
* or {@link org.junit.internal.runners.statements.ExpectException
* ExpectException}) and throws an exception if the next
* {@code statement} takes more than the specified {@code timeout}
* .
* ExpectException}) and throws an exception if the next {@code statement}
* takes more than the specified {@code timeout}.
*/
@Override
public void evaluate() throws Throwable {
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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,9 +25,9 @@ import org.springframework.test.annotation.Repeat;
import org.springframework.util.ClassUtils;
/**
* {@code SpringRepeat} is a custom JUnit 4.5+ {@link Statement} which adds
* support for Spring's {@link Repeat &#064;Repeat} annotation by repeating the
* test for the specified number of times.
* {@code SpringRepeat} is a custom JUnit {@link Statement} which adds support
* for Spring's {@link Repeat @Repeat} annotation by repeating the test for
* the specified number of times.
*
* @see #evaluate()
* @author Sam Brannen
......
/**
*
* <p>JUnit 4.5 based {@code statements} used in the <em>Spring TestContext Framework</em>.</p>
*
* <p>Custom JUnit {@code Statements} used in the <em>Spring TestContext Framework</em>.</p>
*/
package org.springframework.test.context.junit4.statements;
......@@ -2,7 +2,7 @@
* <p>This package contains the <em>Spring TestContext Framework</em> which
* provides annotation-driven unit and integration testing support that is
* agnostic of the actual testing framework in use. The same techniques and
* annotation-based configuration used in, for example, a JUnit 4.5+ environment
* annotation-based configuration used in, for example, a JUnit environment
* can also be applied to tests written with TestNG, etc.
*
* <p>In addition to providing generic and extensible testing infrastructure,
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
......@@ -21,6 +21,7 @@ import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* A replacement of {@link org.hamcrest.MatcherAssert} that removes the need to
......@@ -28,6 +29,7 @@ import org.springframework.util.ClassUtils;
* compatibility with Hamcrest 1.1 (also embedded in JUnit 4.4 through 4.8).
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 3.2
*/
public abstract class MatcherAssertionErrors {
......@@ -66,7 +68,8 @@ public abstract class MatcherAssertionErrors {
description.appendDescriptionOf(matcher);
if (describeMismatchMethod != null) {
description.appendText("\n but: ");
matcher.describeMismatch(actual, description);
// matcher.describeMismatch(actual, description);
ReflectionUtils.invokeMethod(describeMismatchMethod, matcher, actual, description);
}
else {
description.appendText("\n got: ");
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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,25 +16,21 @@
package org.springframework.test.context;
import static org.junit.Assert.*;
import java.util.Comparator;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.SpringRunnerContextCacheTests.OrderedMethodsSpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import static org.junit.Assert.*;
/**
* JUnit 4 based unit test which verifies correct {@link ContextCache
* application context caching} in conjunction with the
......@@ -46,7 +42,8 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe
* @since 2.5
* @see ContextCacheTests
*/
@RunWith(OrderedMethodsSpringJUnit4ClassRunner.class)
@RunWith(SpringJUnit4ClassRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
@ContextConfiguration("junit4/SpringJUnit4ClassRunnerAppCtxTests-context.xml")
public class SpringRunnerContextCacheTests {
......@@ -130,31 +127,4 @@ public class SpringRunnerContextCacheTests {
SpringRunnerContextCacheTests.dirtiedApplicationContext, this.applicationContext);
}
/**
* @since 3.2
*/
public static class OrderedMethodsSpringJUnit4ClassRunner extends SpringJUnit4ClassRunner {
public OrderedMethodsSpringJUnit4ClassRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> testMethods = super.computeTestMethods();
java.util.Collections.sort(testMethods, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod method1, FrameworkMethod method2) {
return method1.getName().compareTo(method2.getName());
}
});
return testMethods;
}
}
}
......@@ -20213,12 +20213,12 @@ work__.
[[testcontext-support-classes-junit4]]
====== JUnit support classes
The `org.springframework.test.context.junit4` package provides support classes for JUnit
4.5+ based test cases.
The `org.springframework.test.context.junit4` package provides support classes for
JUnit-based test cases.
* `AbstractJUnit4SpringContextTests`: Abstract base test class that integrates the
__Spring TestContext Framework__ with explicit `ApplicationContext` testing support in
a JUnit 4.5+ environment.
a JUnit 4.9+ environment.
When you extend `AbstractJUnit4SpringContextTests`, you can access the following
`protected` instance variable:
** `applicationContext`: Use this variable to perform explicit bean lookups or to test
......@@ -20250,8 +20250,8 @@ using `@RunWith(SpringJUnit4ClassRunner.class)`, `@ContextConfiguration`,
[[testcontext-junit4-runner]]
====== Spring JUnit Runner
The __Spring TestContext Framework__ offers full integration with JUnit 4.5+ through a
custom runner (tested on JUnit 4.5 -- 4.11). By annotating test classes with
The __Spring TestContext Framework__ offers full integration with JUnit 4.9+ through a
custom runner (tested on JUnit 4.9 -- 4.11). By annotating test classes with
`@RunWith(SpringJUnit4ClassRunner.class)`, developers can implement standard JUnit-based
unit and integration tests and simultaneously reap the benefits of the TestContext
framework such as support for loading application contexts, dependency injection of test
......@@ -20792,7 +20792,7 @@ tests] of client-side REST tests.
==== PetClinic Example
The PetClinic application, available on
https://github.com/spring-projects/spring-petclinic[Github], illustrates several features
of the __Spring TestContext Framework__ in a JUnit 4.5+ environment. Most test
of the __Spring TestContext Framework__ in a JUnit environment. Most test
functionality is included in the `AbstractClinicTests`, for which a partial listing
is shown below:
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册