Delete deprecated code in the TestContext framework

This commit deletes the deprecated JUnit 3.8 support in the TestContext
Framework.

Issue: SPR-10499
This commit is contained in:
Sam Brannen 2013-04-28 16:05:49 +02:00
parent 4525068f56
commit eb65b2b083
10 changed files with 1 additions and 1305 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -68,7 +68,6 @@ import java.lang.annotation.Target;
* @see ProfileValueSource
* @see ProfileValueSourceConfiguration
* @see ProfileValueUtils
* @see org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
*/

View File

@ -1,399 +0,0 @@
/*
* Copyright 2002-2012 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.junit38;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.annotation.ExpectedException;
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.annotation.ProfileValueSource;
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.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
/**
* <p>
* Abstract base {@link TestCase} which integrates the <i>Spring TestContext
* Framework</i> and explicit {@link ApplicationContext} testing support in a
* <strong>JUnit 3.8</strong> environment.
* </p>
* <p>
* Concrete subclasses:
* </p>
* <ul>
* <li>Typically declare a class-level
* {@link org.springframework.test.context.ContextConfiguration
* &#064;ContextConfiguration} annotation to configure the
* {@link ApplicationContext application context}
* {@link org.springframework.test.context.ContextConfiguration#locations()
* resource locations}. <i>If your test does not need to load an application
* context, you may choose to omit the
* {@link org.springframework.test.context.ContextConfiguration
* &#064;ContextConfiguration} declaration and configure the appropriate
* {@link org.springframework.test.context.TestExecutionListener
* TestExecutionListeners} manually.</i></li>
* <li>Must declare public constructors which match the signatures of
* {@link #AbstractJUnit38SpringContextTests()
* AbstractJUnit38SpringContextTests()} and
* {@link #AbstractJUnit38SpringContextTests(String)
* AbstractJUnit38SpringContextTests(String)} and delegate to
* {@code super();} and {@code super(name);} respectively.</li>
* </ul>
* <p>
* The following list constitutes all annotations currently supported directly
* by {@code AbstractJUnit38SpringContextTests}. <i>(Note that additional
* annotations may be supported by various
* {@link org.springframework.test.context.TestExecutionListener
* TestExecutionListeners})</i>
* </p>
* <ul>
* <li>{@link org.springframework.test.annotation.DirtiesContext
* &#064;DirtiesContext} (via the configured
* {@link DirtiesContextTestExecutionListener}; only supported on methods for
* JUnit 3.8)</li>
* <li>
* {@link org.springframework.test.annotation.ProfileValueSourceConfiguration
* &#064;ProfileValueSourceConfiguration}</li>
* <li>{@link IfProfileValue &#064;IfProfileValue}</li>
* <li>{@link ExpectedException &#064;ExpectedException}</li>
* <li>{@link Timed &#064;Timed}</li>
* <li>{@link Repeat &#064;Repeat}</li>
* </ul>
* <p>
* JUnit 3.8 does not support <i>before class</i> or <i>after class</i>
* lifecycle callbacks. The following
* {@link org.springframework.test.context.TestExecutionListener
* TestExecutionListener} methods are therefore unsupported in a JUnit 3.8
* environment:
* <ul>
* <li>
* {@link org.springframework.test.context.TestExecutionListener#beforeTestClass(org.springframework.test.context.TestContext)
* beforeTestClass()}</li>
* <li>
* {@link org.springframework.test.context.TestExecutionListener#afterTestClass(org.springframework.test.context.TestContext)
* afterTestClass()}</li>
* </ul>
*
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
* @see org.springframework.test.context.TestContext
* @see org.springframework.test.context.TestContextManager
* @see org.springframework.test.context.TestExecutionListeners
* @see AbstractTransactionalJUnit38SpringContextTests
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
* @see org.springframework.test.context.testng.AbstractTestNGSpringContextTests
* @deprecated as of Spring 3.1, in favor of using
* {@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests AbstractJUnit4SpringContextTests}
*/
@Deprecated
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
public abstract class AbstractJUnit38SpringContextTests extends TestCase implements ApplicationContextAware {
private static int disabledTestCount = 0;
/**
* Return the number of tests disabled in this environment.
*/
public static int getDisabledTestCount() {
return disabledTestCount;
}
/**
* Logger available to subclasses.
*/
protected final Log logger = LogFactory.getLog(getClass());
/**
* The {@link ApplicationContext} that was injected into this test instance
* via {@link #setApplicationContext(ApplicationContext)}.
*/
protected ApplicationContext applicationContext;
/**
* {@link ProfileValueSource} available to subclasses but primarily intended
* for internal use to provide support for {@link IfProfileValue
* &#064;IfProfileValue}.
*/
protected final ProfileValueSource profileValueSource;
private final TestContextManager testContextManager;
/**
* Constructs a new AbstractJUnit38SpringContextTests instance; initializes
* the internal {@link TestContextManager} for the current test; and
* retrieves the configured (or default) {@link ProfileValueSource}.
*/
public AbstractJUnit38SpringContextTests() {
super();
this.testContextManager = new TestContextManager(getClass());
this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass());
}
/**
* Constructs a new AbstractJUnit38SpringContextTests instance with the
* supplied {@code name}; initializes the internal
* {@link TestContextManager} for the current test; and retrieves the
* configured (or default) {@link ProfileValueSource}.
*
* @param name the name of the current test to execute
*/
public AbstractJUnit38SpringContextTests(String name) {
super(name);
this.testContextManager = new TestContextManager(getClass());
this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass());
}
/**
* Sets the {@link ApplicationContext} to be used by this test instance,
* provided via {@link ApplicationContextAware} semantics.
*/
public final void setApplicationContext(final ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* Runs the <em>Spring TestContext Framework</em> test sequence.
* <p>
* In addition to standard {@link TestCase#runBare()} semantics, this
* implementation performs the following:
* <ul>
* <li>Calls {@link TestContextManager#prepareTestInstance(Object)
* prepareTestInstance()},
* {@link TestContextManager#beforeTestMethod(Object,Method)
* beforeTestMethod()}, and
* {@link TestContextManager#afterTestMethod(Object,Method,Throwable)
* afterTestMethod()} on this test's {@link TestContextManager} at the
* appropriate test execution points.</li>
* <li>Provides support for {@link IfProfileValue &#064;IfProfileValue}.</li>
* <li>Provides support for {@link Repeat &#064;Repeat}.</li>
* <li>Provides support for {@link Timed &#064;Timed}.</li>
* <li>Provides support for {@link ExpectedException
* &#064;ExpectedException}.</li>
* </ul>
*
* @see ProfileValueUtils#isTestEnabledInThisEnvironment
*/
@Override
public void runBare() throws Throwable {
this.testContextManager.prepareTestInstance(this);
final Method testMethod = getTestMethod();
if (!ProfileValueUtils.isTestEnabledInThisEnvironment(this.profileValueSource, testMethod, getClass())) {
recordDisabled(testMethod);
return;
}
runTestTimed(new TestExecutionCallback() {
public void run() throws Throwable {
runManaged(testMethod);
}
}, testMethod);
}
/**
* Get the current test method.
*/
private Method getTestMethod() {
assertNotNull("TestCase.getName() cannot be null", getName());
Method testMethod = null;
try {
testMethod = getClass().getMethod(getName(), (Class[]) null);
}
catch (NoSuchMethodException ex) {
fail("Method \"" + getName() + "\" not found");
}
if (!Modifier.isPublic(testMethod.getModifiers())) {
fail("Method \"" + getName() + "\" should be public");
}
return testMethod;
}
/**
* Runs a <em>timed</em> test via the supplied {@link TestExecutionCallback}
* , providing support for the {@link Timed &#064;Timed} annotation.
*
* @param tec the test execution callback to run
* @param testMethod the actual test method: used to retrieve the
* {@code timeout}
* @throws Throwable if any exception is thrown
* @see Timed
* @see #runTest
*/
private void runTestTimed(TestExecutionCallback tec, Method testMethod) throws Throwable {
Timed timed = testMethod.getAnnotation(Timed.class);
if (timed == null) {
runTest(tec, testMethod);
}
else {
long startTime = System.currentTimeMillis();
try {
runTest(tec, testMethod);
}
finally {
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed > timed.millis()) {
fail("Took " + elapsed + " ms; limit was " + timed.millis());
}
}
}
}
/**
* Runs a test via the supplied {@link TestExecutionCallback}, providing
* support for the {@link ExpectedException &#064;ExpectedException} and
* {@link Repeat &#064;Repeat} annotations.
*
* @param tec the test execution callback to run
* @param testMethod the actual test method: used to retrieve the
* {@link ExpectedException &#064;ExpectedException} and {@link Repeat
* &#064;Repeat} annotations
* @throws Throwable if any exception is thrown
* @see ExpectedException
* @see Repeat
*/
private void runTest(TestExecutionCallback tec, Method testMethod) throws Throwable {
ExpectedException expectedExceptionAnnotation = testMethod.getAnnotation(ExpectedException.class);
boolean exceptionIsExpected = (expectedExceptionAnnotation != null && expectedExceptionAnnotation.value() != null);
Class<? extends Throwable> expectedException = (exceptionIsExpected ? expectedExceptionAnnotation.value()
: null);
Repeat repeat = testMethod.getAnnotation(Repeat.class);
int runs = ((repeat != null) && (repeat.value() > 1)) ? repeat.value() : 1;
for (int i = 0; i < runs; i++) {
try {
if (runs > 1 && this.logger.isInfoEnabled()) {
this.logger.info("Repetition " + (i + 1) + " of test " + testMethod.getName());
}
tec.run();
if (exceptionIsExpected) {
fail("Expected exception: " + expectedException.getName());
}
}
catch (Throwable ex) {
if (!exceptionIsExpected) {
throw ex;
}
if (!expectedException.isAssignableFrom(ex.getClass())) {
// Wrap the unexpected throwable with an explicit message.
AssertionFailedError assertionError = new AssertionFailedError("Unexpected exception, expected <"
+ expectedException.getName() + "> but was <" + ex.getClass().getName() + ">");
assertionError.initCause(ex);
throw assertionError;
}
}
}
}
/**
* Calls {@link TestContextManager#beforeTestMethod(Object,Method)} and
* {@link TestContextManager#afterTestMethod(Object,Method,Throwable)} at
* the appropriate test execution points.
*
* @param testMethod the test method to run
* @throws Throwable if any exception is thrown
* @see #runBare()
* @see TestCase#runTest()
*/
private void runManaged(Method testMethod) throws Throwable {
Throwable exception = null;
boolean reachedTest = false;
try {
this.testContextManager.beforeTestMethod(this, testMethod);
setUp();
reachedTest = true;
runTest();
}
catch (Throwable ex) {
exception = ex;
}
finally {
try {
if (reachedTest) {
tearDown();
}
}
catch (Throwable ex) {
if (exception == null) {
exception = ex;
}
}
finally {
try {
this.testContextManager.afterTestMethod(this, testMethod, exception);
}
catch (Throwable ex) {
if (exception == null) {
exception = ex;
}
}
}
}
if (exception != null) {
if (exception.getCause() instanceof AssertionError) {
exception = exception.getCause();
}
throw exception;
}
}
/**
* Records the supplied test method as <em>disabled</em> in the current
* environment by incrementing the total number of disabled tests and
* logging a debug message.
*
* @param testMethod the test method that is disabled.
* @see #getDisabledTestCount()
*/
protected void recordDisabled(Method testMethod) {
disabledTestCount++;
if (this.logger.isInfoEnabled()) {
this.logger.info("**** " + getClass().getName() + "." + getName() + "() is disabled in this environment. "
+ "Total disabled tests = " + getDisabledTestCount());
}
}
/**
* Private inner class that defines a callback analogous to {@link Runnable}
* , just declaring Throwable.
*/
private static interface TestExecutionCallback {
void run() throws Throwable;
}
}

View File

@ -1,158 +0,0 @@
/*
* Copyright 2002-2012 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.junit38;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* Abstract {@link Transactional transactional} extension of
* {@link AbstractJUnit38SpringContextTests} which adds convenience
* functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean
* and a {@link PlatformTransactionManager} bean to be defined in the Spring
* {@link ApplicationContext application context}.
* </p>
* <p>
* This class exposes a {@link SimpleJdbcTemplate} and provides an easy way to
* {@link #countRowsInTable(String) count the number of rows in a table} ,
* {@link #deleteFromTables(String...) delete from the database} , and
* {@link #executeSqlScript(String, boolean) execute SQL scripts} within a
* transaction.
* </p>
* <p>
* Concrete subclasses must fulfill the same requirements outlined in
* {@link AbstractJUnit38SpringContextTests}.
* </p>
*
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
* @see AbstractJUnit38SpringContextTests
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.TestExecutionListeners
* @see org.springframework.test.context.transaction.TransactionalTestExecutionListener
* @see org.springframework.test.context.transaction.TransactionConfiguration
* @see org.springframework.transaction.annotation.Transactional
* @see org.springframework.test.annotation.NotTransactional
* @see org.springframework.test.annotation.Rollback
* @see org.springframework.test.context.transaction.BeforeTransaction
* @see org.springframework.test.context.transaction.AfterTransaction
* @see org.springframework.test.jdbc.SimpleJdbcTestUtils
* @see org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests
* @see org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests
* @deprecated as of Spring 3.1, in favor of using
* {@link org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests AbstractTransactionalJUnit4SpringContextTests}
*/
@Deprecated
@TestExecutionListeners(TransactionalTestExecutionListener.class)
@Transactional
public abstract class AbstractTransactionalJUnit38SpringContextTests extends AbstractJUnit38SpringContextTests {
/**
* The SimpleJdbcTemplate that this base class manages, available to subclasses.
*/
protected SimpleJdbcTemplate simpleJdbcTemplate;
private String sqlScriptEncoding;
/**
* Constructs a new AbstractTransactionalJUnit38SpringContextTests instance.
*/
public AbstractTransactionalJUnit38SpringContextTests() {
super();
}
/**
* Constructs a new AbstractTransactionalJUnit38SpringContextTests instance
* with the supplied {@code name}.
* @param name the name of the current test to execute
*/
public AbstractTransactionalJUnit38SpringContextTests(String name) {
super(name);
}
/**
* Set the DataSource, typically provided via Dependency Injection.
* @param dataSource The DataSource to inject
*/
@Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
/**
* 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
*/
protected int countRowsInTable(String tableName) {
return SimpleJdbcTestUtils.countRowsInTable(this.simpleJdbcTemplate, tableName);
}
/**
* 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
*/
protected int deleteFromTables(String... names) {
return SimpleJdbcTestUtils.deleteFromTables(this.simpleJdbcTemplate, names);
}
/**
* Execute the given SQL script. Use with caution outside of a transaction!
* <p>The script will normally be loaded by classpath. There should be one statement
* per line. Any semicolons will be removed. <b>Do not use this method to execute
* DDL if you expect rollback.</b>
* @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 {@code false}
*/
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);
}
}

View File

@ -1,7 +0,0 @@
/**
* <p>Support classes for ApplicationContext-based and transactional
* tests run with JUnit 3.8 and the <em>Spring TestContext Framework</em>.</p>
*/
package org.springframework.test.context.junit38;

View File

@ -1,33 +0,0 @@
<?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">
<bean id="employee" class="org.springframework.tests.sample.beans.Employee">
<property name="name" value="John Smith" />
<property name="age" value="42" />
<property name="company" value="Acme Widgets, Inc." />
</bean>
<bean id="pet" class="org.springframework.tests.sample.beans.Pet">
<constructor-arg value="Fido" />
</bean>
<bean id="foo" class="java.lang.String">
<constructor-arg value="Foo" />
</bean>
<bean id="bar" class="java.lang.String">
<constructor-arg value="Bar" />
</bean>
<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="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:data-source-ref="dataSource" />
<bean id="databaseSetup"
class="org.springframework.test.context.junit4.ConcreteTransactionalJUnit4SpringContextTests$DatabaseSetup" />
</beans>

View File

@ -1,231 +0,0 @@
/*
* Copyright 2002-2013 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.junit38;
import java.util.ArrayList;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.junit.internal.runners.JUnit38ClassRunner;
import org.junit.runner.RunWith;
import org.springframework.tests.sample.beans.Employee;
import org.springframework.tests.sample.beans.Pet;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.annotation.ExpectedException;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.annotation.Timed;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
/**
* Combined integration test for {@link AbstractJUnit38SpringContextTests} and
* {@link AbstractTransactionalJUnit38SpringContextTests}.
*
* @author Sam Brannen
* @since 2.5
*/
@SuppressWarnings("deprecation")
@RunWith(JUnit38ClassRunner.class)
@ContextConfiguration
public class ConcreteTransactionalJUnit38SpringContextTests extends AbstractTransactionalJUnit38SpringContextTests
implements BeanNameAware, InitializingBean {
protected static final String BOB = "bob";
protected static final String JANE = "jane";
protected static final String SUE = "sue";
protected static final String YODA = "yoda";
private boolean beanInitialized = false;
private String beanName = "replace me with [" + getClass().getName() + "]";
private Employee employee;
@Autowired
private Pet pet;
@Autowired(required = false)
protected Long nonrequiredLong;
@Resource()
protected String foo;
protected String bar;
private boolean inTransaction = false;
public ConcreteTransactionalJUnit38SpringContextTests() throws Exception {
this(null);
}
public ConcreteTransactionalJUnit38SpringContextTests(final String name) throws Exception {
super(name);
}
protected static int clearPersonTable(final SimpleJdbcTemplate simpleJdbcTemplate) {
return SimpleJdbcTestUtils.deleteFromTables(simpleJdbcTemplate, "person");
}
protected static void createPersonTable(final SimpleJdbcTemplate simpleJdbcTemplate) {
try {
simpleJdbcTemplate.update("CREATE TABLE person (name VARCHAR(20) NOT NULL, PRIMARY KEY(name))");
}
catch (final BadSqlGrammarException bsge) {
/* ignore */
}
}
protected static int countRowsInPersonTable(final SimpleJdbcTemplate simpleJdbcTemplate) {
return SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "person");
}
protected static int addPerson(final SimpleJdbcTemplate simpleJdbcTemplate, final String name) {
return simpleJdbcTemplate.update("INSERT INTO person VALUES(?)", name);
}
protected static int deletePerson(final SimpleJdbcTemplate simpleJdbcTemplate, final String name) {
return simpleJdbcTemplate.update("DELETE FROM person WHERE name=?", name);
}
@Override
public final void afterPropertiesSet() throws Exception {
this.beanInitialized = true;
}
@Override
public final void setBeanName(final String beanName) {
this.beanName = beanName;
}
@Autowired
protected final void setEmployee(final Employee employee) {
this.employee = employee;
}
@Resource
protected final void setBar(final String bar) {
this.bar = bar;
}
@NotTransactional
@Timed(millis = 10000)
public void testNoOpShouldNotTimeOut() throws Exception {
/* no-op */
}
@NotTransactional
@ExpectedException(IndexOutOfBoundsException.class)
public void testExpectedExceptionAnnotation() {
new ArrayList<Object>().get(1);
}
@NotTransactional
public void testApplicationContextSet() {
assertNotNull("The application context should have been set due to ApplicationContextAware semantics.",
super.applicationContext);
}
@NotTransactional
public void testBeanInitialized() {
assertTrue("This test bean should have been initialized due to InitializingBean semantics.",
this.beanInitialized);
}
@NotTransactional
public void testBeanNameSet() {
assertEquals("The bean name of this test instance should have been set to the fully qualified class name "
+ "due to BeanNameAware semantics.", getClass().getName(), this.beanName);
}
@NotTransactional
public void testAnnotationAutowiredFields() {
assertNull("The nonrequiredLong property should NOT have been autowired.", this.nonrequiredLong);
assertNotNull("The pet field should have been autowired.", this.pet);
assertEquals("Fido", this.pet.getName());
}
@NotTransactional
public void testAnnotationAutowiredMethods() {
assertNotNull("The employee setter method should have been autowired.", this.employee);
assertEquals("John Smith", this.employee.getName());
}
@NotTransactional
public void testResourceAnnotationWiredFields() {
assertEquals("The foo field should have been wired via @Resource.", "Foo", this.foo);
}
@NotTransactional
public void testResourceAnnotationWiredMethods() {
assertEquals("The bar method should have been wired via @Resource.", "Bar", this.bar);
}
@BeforeTransaction
public void beforeTransaction() {
this.inTransaction = true;
assertEquals("Verifying the number of rows in the person table before a transactional test method.", 1,
countRowsInPersonTable(super.simpleJdbcTemplate));
assertEquals("Adding yoda", 1, addPerson(super.simpleJdbcTemplate, YODA));
}
@Override
public void setUp() throws Exception {
assertEquals("Verifying the number of rows in the person table before a test method.", (this.inTransaction ? 2
: 1), countRowsInPersonTable(super.simpleJdbcTemplate));
}
public void testModifyTestDataWithinTransaction() {
assertEquals("Adding jane", 1, addPerson(super.simpleJdbcTemplate, JANE));
assertEquals("Adding sue", 1, addPerson(super.simpleJdbcTemplate, SUE));
assertEquals("Verifying the number of rows in the person table within transactionalMethod2().", 4,
countRowsInPersonTable(super.simpleJdbcTemplate));
}
@Override
public void tearDown() throws Exception {
assertEquals("Verifying the number of rows in the person table after a test method.", (this.inTransaction ? 4
: 1), countRowsInPersonTable(super.simpleJdbcTemplate));
}
@AfterTransaction
public void afterTransaction() {
assertEquals("Deleting yoda", 1, deletePerson(super.simpleJdbcTemplate, YODA));
assertEquals("Verifying the number of rows in the person table after a transactional test method.", 1,
countRowsInPersonTable(super.simpleJdbcTemplate));
}
public static class DatabaseSetup {
@Autowired
void setDataSource(final DataSource dataSource) {
final SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
createPersonTable(simpleJdbcTemplate);
clearPersonTable(simpleJdbcTemplate);
addPerson(simpleJdbcTemplate, BOB);
}
}
}

View File

@ -1,12 +0,0 @@
<?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">
<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="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:data-source-ref="dataSource" />
</beans>

View File

@ -1,156 +0,0 @@
/*
* Copyright 2002-2012 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.junit38;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
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;
/**
* <p>
* JUnit 4 based integration test for verifying that '<em>before</em>' and '<em>after</em>'
* methods of {@link TestExecutionListener TestExecutionListeners} as well as
* {@link BeforeTransaction @BeforeTransaction} and
* {@link AfterTransaction @AfterTransaction} methods can fail a test in a JUnit
* 3.8 environment, as requested in <a
* href="http://opensource.atlassian.com/projects/spring/browse/SPR-3960"
* target="_blank">SPR-3960</a>.
* </p>
*
* @author Sam Brannen
* @since 2.5
*/
@RunWith(Parameterized.class)
public class FailingBeforeAndAfterMethodsTests {
protected final Class<?> clazz;
public FailingBeforeAndAfterMethodsTests(final Class<?> clazz) {
this.clazz = clazz;
}
@Parameters
public static Collection<Object[]> testData() {
return Arrays.asList(new Object[][] {
{ AlwaysFailingBeforeTestMethodTestCase.class },
{ AlwaysFailingAfterTestMethodTestCase.class },
{ FailingBeforeTransactionalTestCase.class },
{ FailingAfterTransactionalTestCase.class }
});
}
@Test
public void runTestAndAssertCounters() throws Exception {
final String testName = "testNothing";
final TestCase testCase = (TestCase) this.clazz.newInstance();
testCase.setName(testName);
TestResult testResult = testCase.run();
assertEquals("Verifying number of errors for test method [" + testName + "] and class [" + this.clazz + "].",
0, testResult.errorCount());
assertEquals("Verifying number of failures for test method [" + testName + "] and class [" + this.clazz + "].",
1, testResult.failureCount());
}
static class AlwaysFailingBeforeTestMethodTestExecutionListener extends AbstractTestExecutionListener {
@Override
@SuppressWarnings("deprecation")
public void beforeTestMethod(TestContext testContext) {
junit.framework.Assert.fail("always failing beforeTestMethod()");
}
}
static class AlwaysFailingAfterTestMethodTestExecutionListener extends AbstractTestExecutionListener {
@Override
@SuppressWarnings("deprecation")
public void afterTestMethod(TestContext testContext) {
junit.framework.Assert.fail("always failing afterTestMethod()");
}
}
@Ignore("TestCase classes are run manually by the enclosing test class")
@SuppressWarnings("deprecation")
@TestExecutionListeners(listeners = AlwaysFailingBeforeTestMethodTestExecutionListener.class, inheritListeners = false)
public static class AlwaysFailingBeforeTestMethodTestCase extends AbstractJUnit38SpringContextTests {
public void testNothing() {
}
}
@Ignore("TestCase classes are run manually by the enclosing test class")
@SuppressWarnings("deprecation")
@TestExecutionListeners(listeners = AlwaysFailingAfterTestMethodTestExecutionListener.class, inheritListeners = false)
public static class AlwaysFailingAfterTestMethodTestCase extends AbstractJUnit38SpringContextTests {
public void testNothing() {
}
}
@Ignore("TestCase classes are run manually by the enclosing test class")
@SuppressWarnings("deprecation")
@ContextConfiguration("FailingBeforeAndAfterMethodsTests-context.xml")
public static class FailingBeforeTransactionalTestCase extends AbstractTransactionalJUnit38SpringContextTests {
public void testNothing() {
}
@BeforeTransaction
public void beforeTransaction() {
fail("always failing beforeTransaction()");
}
}
@Ignore("TestCase classes are run manually by the enclosing test class")
@SuppressWarnings("deprecation")
@ContextConfiguration("FailingBeforeAndAfterMethodsTests-context.xml")
public static class FailingAfterTransactionalTestCase extends AbstractTransactionalJUnit38SpringContextTests {
public void testNothing() {
}
@AfterTransaction
public void afterTransaction() {
fail("always failing afterTransaction()");
}
}
}

View File

@ -1,212 +0,0 @@
/*
* Copyright 2002-2012 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.junit38;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.annotation.ProfileValueSource;
import org.springframework.test.annotation.ProfileValueSourceConfiguration;
import org.springframework.test.annotation.SystemProfileValueSource;
import org.springframework.test.context.TestExecutionListeners;
/**
* Verifies proper handling of {@link IfProfileValue &#064;IfProfileValue} and
* {@link ProfileValueSourceConfiguration &#064;ProfileValueSourceConfiguration}
* in conjunction with {@link AbstractJUnit38SpringContextTests}.
*
* @author Sam Brannen
* @since 2.5
*/
public class ProfileValueJUnit38SpringContextTests extends TestCase {
private static final String EMPTY = "testIfProfileValueEmpty";
private static final String DISABLED_VIA_WRONG_NAME = "testIfProfileValueDisabledViaWrongName";
private static final String DISABLED_VIA_WRONG_VALUE = "testIfProfileValueDisabledViaWrongValue";
private static final String ENABLED_VIA_MULTIPLE_VALUES = "testIfProfileValueEnabledViaMultipleValues";
private static final String ENABLED_VIA_SINGLE_VALUE = "testIfProfileValueEnabledViaSingleValue";
private static final String NOT_CONFIGURED = "testIfProfileValueNotConfigured";
private static final String NAME = "ProfileValueAnnotationAwareTransactionalTests.profile_value.name";
private static final String VALUE = "enigma";
private final Map<String, Integer> expectedInvocationCounts = new HashMap<String, Integer>();
public ProfileValueJUnit38SpringContextTests() {
System.setProperty(NAME, VALUE);
}
@Override
protected void setUp() throws Exception {
this.expectedInvocationCounts.put(EMPTY, 0);
this.expectedInvocationCounts.put(DISABLED_VIA_WRONG_NAME, 0);
this.expectedInvocationCounts.put(DISABLED_VIA_WRONG_VALUE, 0);
this.expectedInvocationCounts.put(ENABLED_VIA_SINGLE_VALUE, 1);
this.expectedInvocationCounts.put(ENABLED_VIA_MULTIPLE_VALUES, 1);
this.expectedInvocationCounts.put(NOT_CONFIGURED, 1);
}
private void configureDisabledClassExpectations() {
this.expectedInvocationCounts.put(ENABLED_VIA_SINGLE_VALUE, 0);
this.expectedInvocationCounts.put(ENABLED_VIA_MULTIPLE_VALUES, 0);
this.expectedInvocationCounts.put(NOT_CONFIGURED, 0);
}
private void runTestAndAssertCounters(Class<? extends DefaultProfileValueSourceTestCase> testCaseType,
String testName, int expectedInvocationCount, int expectedErrorCount, int expectedFailureCount)
throws Exception {
DefaultProfileValueSourceTestCase testCase = testCaseType.newInstance();
testCase.setName(testName);
TestResult testResult = testCase.run();
assertEquals("Verifying number of invocations for test method [" + testName + "].", expectedInvocationCount,
testCase.invocationCount);
assertEquals("Verifying number of errors for test method [" + testName + "].", expectedErrorCount,
testResult.errorCount());
assertEquals("Verifying number of failures for test method [" + testName + "].", expectedFailureCount,
testResult.failureCount());
}
private void runTests(final Class<? extends DefaultProfileValueSourceTestCase> testCaseType) throws Exception {
runTestAndAssertCounters(testCaseType, EMPTY, expectedInvocationCounts.get(EMPTY), 0, 0);
runTestAndAssertCounters(testCaseType, DISABLED_VIA_WRONG_NAME,
expectedInvocationCounts.get(DISABLED_VIA_WRONG_NAME), 0, 0);
runTestAndAssertCounters(testCaseType, DISABLED_VIA_WRONG_VALUE,
expectedInvocationCounts.get(DISABLED_VIA_WRONG_VALUE), 0, 0);
runTestAndAssertCounters(testCaseType, ENABLED_VIA_SINGLE_VALUE,
expectedInvocationCounts.get(ENABLED_VIA_SINGLE_VALUE), 0, 0);
runTestAndAssertCounters(testCaseType, ENABLED_VIA_MULTIPLE_VALUES,
expectedInvocationCounts.get(ENABLED_VIA_MULTIPLE_VALUES), 0, 0);
runTestAndAssertCounters(testCaseType, NOT_CONFIGURED, expectedInvocationCounts.get(NOT_CONFIGURED), 0, 0);
}
public void testDefaultProfileValueSource() throws Exception {
assertEquals("Verifying the type of the configured ProfileValueSource.", SystemProfileValueSource.class,
new DefaultProfileValueSourceTestCase().getProfileValueSource().getClass());
runTests(DefaultProfileValueSourceTestCase.class);
}
public void testHardCodedProfileValueSource() throws Exception {
assertEquals("Verifying the type of the configured ProfileValueSource.", HardCodedProfileValueSource.class,
new HardCodedProfileValueSourceTestCase().getProfileValueSource().getClass());
runTests(HardCodedProfileValueSourceTestCase.class);
}
public void testClassLevelIfProfileValueEnabledSingleValue() throws Exception {
runTests(ClassLevelIfProfileValueEnabledSingleValueTestCase.class);
}
public void testClassLevelIfProfileValueDisabledSingleValue() throws Exception {
configureDisabledClassExpectations();
runTests(ClassLevelIfProfileValueDisabledSingleValueTestCase.class);
}
public void testClassLevelIfProfileValueEnabledMultiValue() throws Exception {
runTests(ClassLevelIfProfileValueEnabledMultiValueTestCase.class);
}
public void testClassLevelIfProfileValueDisabledMultiValue() throws Exception {
configureDisabledClassExpectations();
runTests(ClassLevelIfProfileValueDisabledMultiValueTestCase.class);
}
// -------------------------------------------------------------------
/**
* Note that {@link TestExecutionListeners @TestExecutionListeners} is
* explicitly configured with an empty list, thus disabling all default
* listeners.
*/
@SuppressWarnings("deprecation")
@TestExecutionListeners(listeners = {}, inheritListeners = false)
public static class DefaultProfileValueSourceTestCase extends AbstractJUnit38SpringContextTests {
int invocationCount = 0;
public ProfileValueSource getProfileValueSource() {
return super.profileValueSource;
}
@IfProfileValue(name = NAME, value = "")
public void testIfProfileValueEmpty() {
this.invocationCount++;
fail("An empty profile value should throw an IllegalArgumentException.");
}
@IfProfileValue(name = NAME + "X", value = VALUE)
public void testIfProfileValueDisabledViaWrongName() {
this.invocationCount++;
fail("The body of a disabled test should never be executed!");
}
@IfProfileValue(name = NAME, value = VALUE + "X")
public void testIfProfileValueDisabledViaWrongValue() {
this.invocationCount++;
fail("The body of a disabled test should never be executed!");
}
@IfProfileValue(name = NAME, value = VALUE)
public void testIfProfileValueEnabledViaSingleValue() {
this.invocationCount++;
}
@IfProfileValue(name = NAME, values = { "foo", VALUE, "bar" })
public void testIfProfileValueEnabledViaMultipleValues() {
this.invocationCount++;
}
public void testIfProfileValueNotConfigured() {
this.invocationCount++;
}
}
@ProfileValueSourceConfiguration(HardCodedProfileValueSource.class)
public static class HardCodedProfileValueSourceTestCase extends DefaultProfileValueSourceTestCase {
}
public static class HardCodedProfileValueSource implements ProfileValueSource {
@Override
public String get(final String key) {
return (key.equals(NAME) ? VALUE : null);
}
}
@IfProfileValue(name = NAME, value = VALUE)
public static class ClassLevelIfProfileValueEnabledSingleValueTestCase extends DefaultProfileValueSourceTestCase {
}
@IfProfileValue(name = NAME, value = VALUE + "X")
public static class ClassLevelIfProfileValueDisabledSingleValueTestCase extends DefaultProfileValueSourceTestCase {
}
@IfProfileValue(name = NAME, values = { "foo", VALUE, "bar" })
public static class ClassLevelIfProfileValueEnabledMultiValueTestCase extends DefaultProfileValueSourceTestCase {
}
@IfProfileValue(name = NAME, values = { "foo", "bar", "baz" })
public static class ClassLevelIfProfileValueDisabledMultiValueTestCase extends DefaultProfileValueSourceTestCase {
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright 2002-2012 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.junit38;
import junit.framework.TestCase;
import org.springframework.test.annotation.Repeat;
import org.springframework.test.context.TestExecutionListeners;
/**
* Unit test for {@link AbstractJUnit38SpringContextTests} which focuses on
* proper support of the {@link Repeat @Repeat} annotation.
*
* @author Sam Brannen
* @since 2.5
*/
public class RepeatedJUnit38SpringContextTests extends TestCase {
public RepeatedJUnit38SpringContextTests() throws Exception {
super();
}
public RepeatedJUnit38SpringContextTests(final String name) throws Exception {
super(name);
}
private void assertRepetitions(final String testName, final int expectedNumInvocations) throws Exception {
final RepeatedTestCase repeatedTestCase = new RepeatedTestCase(testName);
repeatedTestCase.run();
assertEquals("Verifying number of invocations for test method [" + testName + "].", expectedNumInvocations,
repeatedTestCase.invocationCount);
}
public void testRepeatAnnotationSupport() throws Exception {
assertRepetitions("testNonAnnotated", 1);
assertRepetitions("testNegativeRepeatValue", 1);
assertRepetitions("testDefaultRepeatValue", 1);
assertRepetitions("testRepeatedFiveTimes", 5);
}
/**
* Note that {@link TestExecutionListeners @TestExecutionListeners} is
* explicitly configured with an empty list, thus disabling all default
* listeners.
*/
@SuppressWarnings("deprecation")
@TestExecutionListeners(listeners = {}, inheritListeners = false)
public static class RepeatedTestCase extends AbstractJUnit38SpringContextTests {
int invocationCount = 0;
public RepeatedTestCase(final String name) throws Exception {
super(name);
}
@Override
protected void setUp() throws Exception {
this.invocationCount++;
}
public void testNonAnnotated() {
/* no-op */
}
@Repeat(-5)
public void testNegativeRepeatValue() {
/* no-op */
}
@Repeat
public void testDefaultRepeatValue() {
/* no-op */
}
@Repeat(5)
public void testRepeatedFiveTimes() {
/* no-op */
}
}
}