diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java index 39fc1d7905..864e846bd5 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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,7 +19,6 @@ 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; import org.springframework.context.ApplicationContextAware; import org.springframework.test.context.ContextConfiguration; @@ -31,18 +30,17 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe /** *
- * Abstract base test class which integrates the - * Spring TestContext Framework with explicit - * {@link ApplicationContext} testing support in a JUnit 4.4 - * environment. + * Abstract base test class which integrates the Spring TestContext + * Framework with explicit {@link ApplicationContext} testing support in a + * JUnit 4.5 environment. *
** Concrete subclasses should typically declare a class-level - * {@link ContextConfiguration @ContextConfiguration} annotation to configure - * the {@link ApplicationContext application context} + * {@link ContextConfiguration @ContextConfiguration} annotation to + * configure the {@link ApplicationContext application context} * {@link ContextConfiguration#locations() resource locations}. * If your test does not need to load an application context, you may choose - * to omit the {@link ContextConfiguration @ContextConfiguration} declaration + * to omit the {@link ContextConfiguration @ContextConfiguration} declaration * and to configure the appropriate * {@link org.springframework.test.context.TestExecutionListener TestExecutionListeners} * manually. @@ -51,11 +49,11 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe * Note: this class serves only as a convenience for extension. If you do not * wish for your test classes to be tied to a Spring-specific class hierarchy, * you may configure your own custom test classes by using - * {@link SpringJUnit4ClassRunner}, - * {@link ContextConfiguration @ContextConfiguration}, - * {@link TestExecutionListeners @TestExecutionListeners}, etc. + * {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration + * @ContextConfiguration}, {@link TestExecutionListeners + * @TestExecutionListeners}, etc. *
- * + * * @author Sam Brannen * @since 2.5 * @see ContextConfiguration @@ -66,7 +64,7 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe * @see org.springframework.test.context.testng.AbstractTestNGSpringContextTests */ @RunWith(SpringJUnit4ClassRunner.class) -@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) +@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class }) public abstract class AbstractJUnit4SpringContextTests implements ApplicationContextAware { /** diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java index 44703fe713..2f73fca311 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java @@ -54,12 +54,12 @@ import org.springframework.transaction.annotation.Transactional; * Note: this class serves only as a convenience for extension. If you do not * wish for your test classes to be tied to a Spring-specific class hierarchy, * you may configure your own custom test classes by using - * {@link SpringJUnit4ClassRunner}, - * {@link ContextConfiguration @ContextConfiguration}, - * {@link TestExecutionListeners @TestExecutionListeners}, - * {@link Transactional @Transactional}, etc. + * {@link SpringJUnit4ClassRunner}, {@link ContextConfiguration + * @ContextConfiguration}, {@link TestExecutionListeners + * @TestExecutionListeners}, {@link Transactional @Transactional}, + * etc. * - * + * * @author Sam Brannen * @author Juergen Hoeller * @since 2.5 @@ -77,12 +77,13 @@ import org.springframework.transaction.annotation.Transactional; * @see org.springframework.test.context.junit38.AbstractTransactionalJUnit38SpringContextTests * @see org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests */ -@TestExecutionListeners({TransactionalTestExecutionListener.class}) +@TestExecutionListeners( { TransactionalTestExecutionListener.class }) @Transactional public abstract class AbstractTransactionalJUnit4SpringContextTests extends AbstractJUnit4SpringContextTests { /** - * The SimpleJdbcTemplate that this base class manages, available to subclasses. + * The SimpleJdbcTemplate that this base class manages, available to + * subclasses. */ protected SimpleJdbcTemplate simpleJdbcTemplate; @@ -98,16 +99,18 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst } /** - * Specify the encoding for SQL scripts, if different from the platform encoding. + * Specify the encoding for SQL scripts, if different from the platform + * encoding. + * * @see #executeSqlScript */ public void setSqlScriptEncoding(String sqlScriptEncoding) { this.sqlScriptEncoding = sqlScriptEncoding; } - /** * Count the rows in the given table. + * * @param tableName table name to count rows in * @return the number of rows in the table */ @@ -116,8 +119,9 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst } /** - * Convenience method for deleting all rows from the specified tables. - * Use with caution outside of a transaction! + * Convenience method for deleting all rows from the specified tables. Use + * with caution outside of a transaction! + * * @param names the names of the tables from which to delete * @return the total number of rows deleted from all specified tables */ @@ -127,21 +131,22 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst /** * Execute the given SQL script. Use with caution outside of a transaction! - *The script will normally be loaded by classpath. There should be one statement - * per line. Any semicolons will be removed. Do not use this method to execute - * DDL if you expect rollback. + *
+ * The script will normally be loaded by classpath. There should be one
+ * statement per line. Any semicolons will be removed. Do not use this
+ * method to execute DDL if you expect rollback.
+ *
* @param sqlResourcePath the Spring resource path for the SQL script
* @param continueOnError whether or not to continue without throwing an
* exception in the event of an error
* @throws DataAccessException if there is an error executing a statement
* and continueOnError was false
*/
- protected void executeSqlScript(String sqlResourcePath, boolean continueOnError)
- throws DataAccessException {
+ protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
Resource resource = this.applicationContext.getResource(sqlResourcePath);
- SimpleJdbcTestUtils.executeSqlScript(
- this.simpleJdbcTemplate, new EncodedResource(resource, this.sqlScriptEncoding), continueOnError);
+ SimpleJdbcTestUtils.executeSqlScript(this.simpleJdbcTemplate, new EncodedResource(resource,
+ this.sqlScriptEncoding), continueOnError);
}
}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java
index 1b240b0c62..cb5569110e 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -26,39 +26,43 @@ import org.junit.internal.runners.JUnit4ClassRunner;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
-
import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.test.context.TestContextManager;
/**
*
* SpringJUnit4ClassRunner is a custom extension of {@link JUnit4ClassRunner} - * which provides functionality of the Spring TestContext Framework - * to standard JUnit 4.4+ tests by means of the {@link TestContextManager} and + * which provides functionality of the Spring TestContext Framework to + * standard JUnit 4.5+ tests by means of the {@link TestContextManager} and * associated support classes and annotations. *
** The following list constitutes all annotations currently supported directly - * by SpringJUnit4ClassRunner. - * (Note that additional annotations may be supported by various - * {@link org.springframework.test.context.TestExecutionListener TestExecutionListeners}) + * by SpringJUnit4ClassRunner. (Note that additional annotations + * may be supported by various + * {@link org.springframework.test.context.TestExecutionListener + * TestExecutionListeners}) *
*NOTE: As of Spring 3.0 M1, SpringJUnit4ClassRunner requires - * JUnit 4.5, while internally still being based on JUnit 4.4 SPI. - * This will be rewritten based on JUnit 4.5's BlockJUnit4ClassRunner - * in a later Spring 3.0 release. - * + *
+ * NOTE: As of Spring 3.0 M1, SpringJUnit4ClassRunner requires JUnit 4.5, + * while internally still being based on JUnit 4.4 SPI. This will be rewritten + * based on JUnit 4.5's BlockJUnit4ClassRunner in a later Spring 3.0 release. + *
+ * * @author Sam Brannen * @author Juergen Hoeller * @since 2.5 @@ -75,6 +79,7 @@ public class SpringJUnit4ClassRunner extends JUnit4ClassRunner { * Constructs a newSpringJUnit4ClassRunner
and initializes a
* {@link TestContextManager} to provide Spring testing functionality to
* standard JUnit tests.
+ *
* @param clazz the Class object corresponding to the test class to be run
* @see #createTestContextManager(Class)
*/
@@ -86,15 +91,16 @@ public class SpringJUnit4ClassRunner extends JUnit4ClassRunner {
this.testContextManager = createTestContextManager(clazz);
}
-
- @Override
/**
- * Check whether the test is enabled in the first place. This prevents classes with
- * a non-matching @IfProfileValue
annotation from running altogether,
- * even skipping the execution of prepareTestInstance
listener methods.
+ * Check whether the test is enabled in the first place. This prevents
+ * classes with a non-matching @IfProfileValue
annotation
+ * from running altogether, even skipping the execution of
+ * prepareTestInstance
listener methods.
+ *
* @see org.springframework.test.annotation.IfProfileValue
* @see org.springframework.test.context.TestExecutionListener
*/
+ @Override
public void run(RunNotifier notifier) {
if (!ProfileValueUtils.isTestEnabledInThisEnvironment(getTestClass().getJavaClass())) {
notifier.fireTestIgnored(getDescription());
@@ -108,6 +114,7 @@ public class SpringJUnit4ClassRunner extends JUnit4ClassRunner {
* instance and then to a {@link TestContextManager} to
* {@link TestContextManager#prepareTestInstance(Object) prepare} the test
* instance for Spring testing functionality.
+ *
* @see JUnit4ClassRunner#createTest()
* @see TestContextManager#prepareTestInstance(Object)
*/
@@ -119,8 +126,11 @@ public class SpringJUnit4ClassRunner extends JUnit4ClassRunner {
}
/**
- * Creates a new {@link TestContextManager}. Can be overridden by subclasses.
- * @param clazz the Class object corresponding to the test class to be managed
+ * Creates a new {@link TestContextManager}. Can be overridden by
+ * subclasses.
+ *
+ * @param clazz the Class object corresponding to the test class to be
+ * managed
*/
protected TestContextManager createTestContextManager(Class> clazz) {
return new TestContextManager(clazz);
@@ -136,6 +146,7 @@ public class SpringJUnit4ClassRunner extends JUnit4ClassRunner {
/**
* Invokes the supplied {@link Method test method} and notifies the supplied
* {@link RunNotifier} of the appropriate events.
+ *
* @see #createTest()
* @see JUnit4ClassRunner#invokeTestMethod(Method,RunNotifier)
*/
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunSpringTestContextAfters.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunSpringTestContextAfters.java
new file mode 100644
index 0000000000..2912003dc8
--- /dev/null
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunSpringTestContextAfters.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 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 java.util.ArrayList;
+import java.util.List;
+
+import org.junit.internal.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.springframework.test.context.TestContextManager;
+
+/**
+ * RunSpringTestContextAfters
is a custom JUnit 4.5+
+ * {@link Statement} which allows the Spring TestContext Framework to
+ * be plugged into the JUnit execution chain by calling
+ * {@link TestContextManager#afterTestMethod(Object, Method) afterTestMethod()}
+ * on the supplied {@link TestContextManager}.
+ *
+ * @see #evaluate()
+ * @see RunSpringTestContextBefores
+ * @author Sam Brannen
+ * @since 3.0
+ */
+public class RunSpringTestContextAfters extends Statement {
+
+ private final Statement next;
+
+ private final Object testInstance;
+
+ private final Method testMethod;
+
+ private final TestContextManager testContextManager;
+
+
+ /**
+ * Constructs a new RunSpringTestContextAfters
statement.
+ *
+ * @param next the next Statement
in the execution chain
+ * @param testInstance the current test instance (never null
)
+ * @param testMethod the test method which has just been executed on the
+ * test instance
+ * @param testContextManager the TestContextManager upon which to call
+ * afterTestMethod()
+ */
+ public RunSpringTestContextAfters(Statement next, Object testInstance, Method testMethod,
+ TestContextManager testContextManager) {
+ this.next = next;
+ this.testInstance = testInstance;
+ this.testMethod = testMethod;
+ this.testContextManager = testContextManager;
+ }
+
+ /**
+ * 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)} with the first
+ * caught exception (if any). If the call to afterTestMethod()
+ * throws an exception, it will also be tracked. Multiple exceptions will be
+ * combined into a {@link MultipleFailureException}.
+ */
+ @Override
+ public void evaluate() throws Throwable {
+ Throwable testException = null;
+ ListRunSpringTestContextBefores
is a custom JUnit 4.5+
+ * {@link Statement} which allows the Spring TestContext Framework to
+ * be plugged into the JUnit execution chain by calling
+ * {@link TestContextManager#beforeTestMethod(Object, Method)
+ * beforeTestMethod()} on the supplied {@link TestContextManager}.
+ *
+ * @see #evaluate()
+ * @see RunSpringTestContextAfters
+ * @author Sam Brannen
+ * @since 3.0
+ */
+public class RunSpringTestContextBefores extends Statement {
+
+ private final Statement next;
+
+ private final Object testInstance;
+
+ private final Method testMethod;
+
+ private final TestContextManager testContextManager;
+
+
+ /**
+ * Constructs a new RunSpringTestContextBefores
statement.
+ *
+ * @param next the next Statement
in the execution chain
+ * @param testInstance the current test instance (never null
)
+ * @param testMethod the test method which is about to be executed on the
+ * test instance
+ * @param testContextManager the TestContextManager upon which to call
+ * beforeTestMethod()
+ */
+ public RunSpringTestContextBefores(Statement next, Object testInstance, Method testMethod,
+ TestContextManager testContextManager) {
+ this.next = next;
+ this.testInstance = testInstance;
+ this.testMethod = testMethod;
+ this.testContextManager = testContextManager;
+ }
+
+ /**
+ * 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 {
+ this.testContextManager.beforeTestMethod(this.testInstance, this.testMethod);
+ this.next.evaluate();
+ }
+
+}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeout.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeout.java
new file mode 100644
index 0000000000..82b7e929ee
--- /dev/null
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeout.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009 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.util.concurrent.TimeoutException;
+
+import org.junit.runners.model.Statement;
+import org.springframework.test.annotation.Timed;
+
+/**
+ * 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.
+ *
+ * @see #evaluate()
+ * @author Sam Brannen
+ * @since 3.0
+ */
+public class SpringFailOnTimeout extends Statement {
+
+ private final Statement next;
+
+ private final long timeout;
+
+
+ /**
+ * Constructs a new SpringFailOnTimeout
statement.
+ *
+ * @param next the next Statement
in the execution chain
+ * @param timeout the configured timeout
for the current test
+ * @see Timed#millis()
+ */
+ public SpringFailOnTimeout(Statement next, long timeout) {
+ this.next = next;
+ this.timeout = timeout;
+ }
+
+ /**
+ * Invokes 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 throws an exception if the next
+ * statement
takes more than the specified timeout
+ * .
+ */
+ @Override
+ public void evaluate() throws Throwable {
+ long startTime = System.currentTimeMillis();
+ try {
+ this.next.evaluate();
+ }
+ finally {
+ long elapsed = System.currentTimeMillis() - startTime;
+ if (elapsed > this.timeout) {
+ throw new TimeoutException(String.format("Test took %s ms; limit was %s ms.", elapsed, this.timeout));
+ }
+ }
+ }
+
+}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/SpringRepeat.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/SpringRepeat.java
new file mode 100644
index 0000000000..e18a3682b3
--- /dev/null
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/SpringRepeat.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009 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.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.runners.model.Statement;
+import org.springframework.test.annotation.Repeat;
+import org.springframework.util.ClassUtils;
+
+/**
+ * SpringRepeat
is a custom JUnit 4.5+ {@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
+ * @since 3.0
+ */
+public class SpringRepeat extends Statement {
+
+ protected static final Log logger = LogFactory.getLog(SpringRepeat.class);
+
+ private final Statement next;
+
+ private final Method testMethod;
+
+ private final int repeat;
+
+
+ /**
+ * Constructs a new SpringRepeat
statement.
+ *
+ * @param next the next Statement
in the execution chain
+ * @param testMethod the current test method
+ * @param repeat the configured repeat count for the current test method
+ * @see Repeat#value()
+ */
+ public SpringRepeat(Statement next, Method testMethod, int repeat) {
+ this.next = next;
+ this.testMethod = testMethod;
+ this.repeat = Math.max(1, repeat);
+ }
+
+ /**
+ * Invokes the next {@link Statement statement} in the execution chain for
+ * the specified repeat count.
+ */
+ @Override
+ public void evaluate() throws Throwable {
+ for (int i = 0; i < this.repeat; i++) {
+ if (this.repeat > 1 && logger.isInfoEnabled()) {
+ logger.info(String.format("Repetition %d of test %s#%s()", (i + 1),
+ ClassUtils.getShortName(this.testMethod.getDeclaringClass()), this.testMethod.getName()));
+ }
+ this.next.evaluate();
+ }
+ }
+
+}