Simplify legacy JUnit 3.8 based tests in spring-orm
This is in preparation for a migration from JUnit 3 to JUnit 4. Issue: SPR-13514, SPR-13515
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.orm.jpa;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.test.jpa.AbstractJpaTests;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
@@ -27,22 +26,22 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class AbstractEntityManagerFactoryIntegrationTests extends AbstractJpaTests {
|
||||
public abstract class AbstractEntityManagerFactoryIntegrationTests extends org.springframework.test.jpa.AbstractJpaTests {
|
||||
|
||||
public static final String[] ECLIPSELINK_CONFIG_LOCATIONS = new String[] {
|
||||
protected static final String[] ECLIPSELINK_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/eclipselink/eclipselink-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
public static final String[] HIBERNATE_CONFIG_LOCATIONS = new String[] {
|
||||
protected static final String[] HIBERNATE_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/hibernate/hibernate-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
public static final String[] OPENJPA_CONFIG_LOCATIONS = new String[] {
|
||||
protected static final String[] OPENJPA_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/openjpa/openjpa-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
|
||||
public static Provider getProvider() {
|
||||
private static Provider getProvider() {
|
||||
String provider = System.getProperty("org.springframework.orm.jpa.provider");
|
||||
if (provider != null) {
|
||||
if (provider.toLowerCase().contains("hibernate")) {
|
||||
@@ -63,7 +62,7 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests extends Abstr
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
protected String[] getConfigPaths() {
|
||||
Provider provider = getProvider();
|
||||
switch (provider) {
|
||||
case ECLIPSELINK:
|
||||
@@ -91,7 +90,7 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests extends Abstr
|
||||
}
|
||||
|
||||
|
||||
public enum Provider {
|
||||
static enum Provider {
|
||||
|
||||
ECLIPSELINK, HIBERNATE, OPENJPA
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ public class ApplicationManagedEntityManagerIntegrationTests extends AbstractEnt
|
||||
assertTrue("EntityManagerFactory is proxied", Proxy.isProxyClass(entityManagerFactory.getClass()));
|
||||
}
|
||||
|
||||
@Transactional(readOnly=true)
|
||||
@Transactional(readOnly = true)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testEntityManagerProxyIsProxy() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
assertTrue(Proxy.isProxyClass(em.getClass()));
|
||||
|
||||
@@ -60,6 +60,7 @@ public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntit
|
||||
assertSame(in2, dex.getCause());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testEntityManagerProxyIsProxy() {
|
||||
EntityManager em = createContainerManagedEntityManager();
|
||||
assertTrue(Proxy.isProxyClass(em.getClass()));
|
||||
|
||||
@@ -47,6 +47,7 @@ import static org.mockito.BDDMockito.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class JpaTransactionManagerTests {
|
||||
|
||||
private EntityManagerFactory factory;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,6 +47,7 @@ import static org.mockito.BDDMockito.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class LocalContainerEntityManagerFactoryBeanTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
// Static fields set by inner class DummyPersistenceProvider
|
||||
@@ -305,6 +306,7 @@ public class LocalContainerEntityManagerFactoryBeanTests extends AbstractEntityM
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class DummyContainerPersistenceProvider implements PersistenceProvider {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,6 +33,7 @@ import static org.mockito.BDDMockito.*;
|
||||
* @author Rod Johnson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class LocalEntityManagerFactoryBeanTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
// Static fields set by inner class DummyPersistenceProvider
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
public class EclipseLinkEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
protected String[] getConfigPaths() {
|
||||
return ECLIPSELINK_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,7 +33,7 @@ public class HibernateEntityManagerFactoryIntegrationTests extends
|
||||
AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
protected String[] getConfigPaths() {
|
||||
return HIBERNATE_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,19 +30,19 @@ import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrat
|
||||
public class HibernateMultiEntityManagerFactoryIntegrationTests extends
|
||||
AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
private EntityManagerFactory entityManagerFactory2;
|
||||
|
||||
|
||||
public HibernateMultiEntityManagerFactoryIntegrationTests() {
|
||||
{
|
||||
setAutowireMode(AUTOWIRE_BY_NAME);
|
||||
}
|
||||
|
||||
private EntityManagerFactory entityManagerFactory2;
|
||||
|
||||
|
||||
public void setEntityManagerFactory2(EntityManagerFactory entityManagerFactory2) {
|
||||
this.entityManagerFactory2 = entityManagerFactory2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
protected String[] getConfigPaths() {
|
||||
return new String[] {
|
||||
"/org/springframework/orm/jpa/hibernate/hibernate-manager-multi.xml",
|
||||
"/org/springframework/orm/jpa/memdb.xml",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,7 +40,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||
public class OpenJpaEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
protected String[] getConfigPaths() {
|
||||
return OPENJPA_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ public class OpenJpaEntityManagerFactoryIntegrationTests extends AbstractContain
|
||||
assertNotNull(openJPAEntityManager.getDelegate());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSavepoint() {
|
||||
TransactionTemplate tt = new TransactionTemplate(transactionManager);
|
||||
tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.orm.jpa.openjpa;
|
||||
|
||||
|
||||
/**
|
||||
* Test that AspectJ weaving (in particular the currently shipped aspects) works
|
||||
* with JPA (see SPR-3873 for more details).
|
||||
@@ -27,7 +26,7 @@ package org.springframework.orm.jpa.openjpa;
|
||||
public class OpenJpaEntityManagerFactoryWithAspectJWeavingIntegrationTests extends OpenJpaEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
protected String[] getConfigPaths() {
|
||||
return new String[] {
|
||||
"/org/springframework/orm/jpa/openjpa/openjpa-manager-aspectj-weaving.xml",
|
||||
"/org/springframework/orm/jpa/memdb.xml",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.orm.jpa.support;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.orm.jpa.AbstractEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.support.PersistenceInjectionTests.DefaultPublicPersistenceContextSetter;
|
||||
@@ -26,34 +24,30 @@ import org.springframework.orm.jpa.support.PersistenceInjectionTests.DefaultPubl
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PersistenceInjectionIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private DefaultPublicPersistenceContextSetter defaultSetterInjected;
|
||||
|
||||
private DefaultPublicPersistenceUnitSetterNamedPerson namedSetterInjected;
|
||||
|
||||
|
||||
public PersistenceInjectionIntegrationTests() {
|
||||
// Enable support for @Autowired
|
||||
{
|
||||
setAutowireMode(AUTOWIRE_NO);
|
||||
setDependencyCheck(false);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private void init(DefaultPublicPersistenceUnitSetterNamedPerson namedSetterInjected) {
|
||||
this.namedSetterInjected = namedSetterInjected;
|
||||
}
|
||||
private DefaultPublicPersistenceContextSetter defaultSetterInjected;
|
||||
|
||||
@Autowired
|
||||
private DefaultPublicPersistenceUnitSetterNamedPerson namedSetterInjected;
|
||||
|
||||
|
||||
public void testDefaultSetterInjection() {
|
||||
EntityManager injectedEm = defaultSetterInjected.getEntityManager();
|
||||
assertNotNull("Default PersistenceContext Setter was injected", injectedEm);
|
||||
public void testDefaultPersistenceContextSetterInjection() {
|
||||
assertNotNull(defaultSetterInjected.getEntityManager());
|
||||
}
|
||||
|
||||
public void testSetterInjectionOfNamedPersistenceContext() {
|
||||
assertNotNull("Named PersistenceContext Setter was injected", namedSetterInjected.getEntityManagerFactory());
|
||||
assertNotNull(namedSetterInjected.getEntityManagerFactory());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import javax.persistence.PersistenceProperty;
|
||||
import javax.persistence.PersistenceUnit;
|
||||
|
||||
import org.hibernate.ejb.HibernateEntityManager;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -58,6 +59,7 @@ import static org.mockito.BDDMockito.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
@@ -189,7 +191,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void testPublicExtendedPersistenceContextSetterWithEntityManagerInfoAndSerialization() throws Exception {
|
||||
EntityManager mockEm = mock(EntityManager.class, withSettings().serializable());
|
||||
given(mockEm.isOpen()).willReturn(true);
|
||||
@@ -717,6 +719,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static class FactoryBeanWithPersistenceContextField implements FactoryBean {
|
||||
|
||||
@PersistenceContext
|
||||
@@ -840,6 +843,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
|
||||
public static class SetterOfWrongTypeAnnotatedWithPersistenceUnit {
|
||||
|
||||
@PersistenceUnit
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void setSomething(Comparable c) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
|
||||
/**
|
||||
* This class is only used within tests in the spring-orm module.
|
||||
*
|
||||
* <p>Java 5 specific subclass of
|
||||
* {@link AbstractTransactionalDataSourceSpringContextTests}, obeying annotations
|
||||
* for transaction control.
|
||||
*
|
||||
* <p>For example, test methods can be annotated with the regular Spring
|
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
|
||||
* annotation — for example, to force execution in a read-only transaction
|
||||
* or to prevent any transaction from being created at all by setting the propagation
|
||||
* level to {@code NOT_SUPPORTED}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based TestContext framework
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractAnnotationAwareTransactionalTests extends
|
||||
AbstractTransactionalDataSourceSpringContextTests {
|
||||
|
||||
private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractAnnotationAwareTransactionalTests, which
|
||||
* delegates to {@link #AbstractAnnotationAwareTransactionalTests(String)}.
|
||||
*/
|
||||
public AbstractAnnotationAwareTransactionalTests() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new AbstractAnnotationAwareTransactionalTests instance with
|
||||
* the specified JUnit {@code name}.
|
||||
* @param name the name of the current test
|
||||
*/
|
||||
public AbstractAnnotationAwareTransactionalTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to populate transaction definition from annotations.
|
||||
*/
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
// getName will return the name of the method being run.
|
||||
if (isDisabledInThisEnvironment(getName())) {
|
||||
// Let superclass log that we didn't run the test.
|
||||
super.runBare();
|
||||
return;
|
||||
}
|
||||
|
||||
final Method testMethod = getTestMethod();
|
||||
|
||||
TransactionDefinition explicitTransactionDefinition = this.transactionAttributeSource.getTransactionAttribute(
|
||||
testMethod, getClass());
|
||||
if (explicitTransactionDefinition != null) {
|
||||
this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method ["
|
||||
+ getName() + "].");
|
||||
setTransactionDefinition(explicitTransactionDefinition);
|
||||
}
|
||||
|
||||
if (this.transactionDefinition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
|
||||
preventTransaction();
|
||||
}
|
||||
|
||||
super.runBare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current test method.
|
||||
*/
|
||||
protected Method getTestMethod() {
|
||||
assertNotNull("TestCase.getName() cannot be null", getName());
|
||||
Method testMethod = null;
|
||||
try {
|
||||
// Use same algorithm as JUnit itself to retrieve the test method
|
||||
// about to be executed (the method name is returned by getName). It
|
||||
// has to be public so we can retrieve it.
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not to roll back transactions for the current test.
|
||||
* <p>The default implementation simply delegates to {@link #isDefaultRollback()}.
|
||||
* @return the <em>rollback</em> flag for the current test
|
||||
*/
|
||||
@Override
|
||||
protected boolean isRollback() {
|
||||
boolean rollback = isDefaultRollback();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Using default rollback [" + rollback + "] for test [" + getName() + "].");
|
||||
}
|
||||
return rollback;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,12 +16,6 @@
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -29,38 +23,18 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* This class is only used within tests in the spring-orm module.
|
||||
*
|
||||
* <p>
|
||||
* Convenient superclass for JUnit 3.8 based tests depending on a Spring
|
||||
* <p>Convenient superclass for JUnit 3.8 based tests depending on a Spring
|
||||
* context. The test instance itself is populated by Dependency Injection.
|
||||
* </p>
|
||||
* <p>
|
||||
* Really for integration testing, not unit testing. You should <i>not</i>
|
||||
* normally use the Spring container for unit tests: simply populate your POJOs
|
||||
* in plain JUnit tests!
|
||||
* </p>
|
||||
* <p>
|
||||
* This supports two modes of populating the test:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Via Setter Dependency Injection. Simply express dependencies on objects
|
||||
* in the test fixture, and they will be satisfied by autowiring by type.
|
||||
* <li>Via Field Injection. Declare protected variables of the required type
|
||||
* which match named beans in the context. This is autowire by name, rather than
|
||||
* type. This approach is based on an approach originated by Ara Abrahmian.
|
||||
* Setter Dependency Injection is the default: set the
|
||||
* {@code populateProtectedVariables} property to {@code true} in
|
||||
* the constructor to switch on Field Injection.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Supports Setter Dependency Injection: simply express dependencies
|
||||
* on objects in the test fixture, and they will be satisfied by autowiring
|
||||
* by type.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
* @author Sam Brannen
|
||||
* @since 1.1.1
|
||||
* @see #setDirty
|
||||
* @see #contextKey
|
||||
* @see #getContext
|
||||
* @see #getConfigLocations
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@@ -69,64 +43,26 @@ public abstract class AbstractDependencyInjectionSpringContextTests extends Abst
|
||||
|
||||
/**
|
||||
* Constant that indicates no autowiring at all.
|
||||
*
|
||||
* @see #setAutowireMode
|
||||
*/
|
||||
public static final int AUTOWIRE_NO = 0;
|
||||
protected static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
|
||||
|
||||
/**
|
||||
* Constant that indicates autowiring bean properties by name.
|
||||
*
|
||||
* @see #setAutowireMode
|
||||
*/
|
||||
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
|
||||
protected static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
|
||||
|
||||
/**
|
||||
* Constant that indicates autowiring bean properties by type.
|
||||
*
|
||||
* @see #setAutowireMode
|
||||
*/
|
||||
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
|
||||
|
||||
private boolean populateProtectedVariables = false;
|
||||
protected static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
|
||||
|
||||
private int autowireMode = AUTOWIRE_BY_TYPE;
|
||||
|
||||
private boolean dependencyCheck = true;
|
||||
|
||||
private String[] managedVariableNames;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractDependencyInjectionSpringContextTests.
|
||||
*/
|
||||
public AbstractDependencyInjectionSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractDependencyInjectionSpringContextTests with a
|
||||
* JUnit name.
|
||||
* @param name the name of this text fixture
|
||||
*/
|
||||
public AbstractDependencyInjectionSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to populate protected variables of this test case. Default is
|
||||
* {@code false}.
|
||||
*/
|
||||
public final void setPopulateProtectedVariables(boolean populateFields) {
|
||||
this.populateProtectedVariables = populateFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to populate protected variables of this test case.
|
||||
*/
|
||||
public final boolean isPopulateProtectedVariables() {
|
||||
return this.populateProtectedVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autowire mode for test properties set by Dependency Injection.
|
||||
@@ -136,14 +72,14 @@ public abstract class AbstractDependencyInjectionSpringContextTests extends Abst
|
||||
* @see #AUTOWIRE_BY_NAME
|
||||
* @see #AUTOWIRE_NO
|
||||
*/
|
||||
public final void setAutowireMode(final int autowireMode) {
|
||||
protected final void setAutowireMode(final int autowireMode) {
|
||||
this.autowireMode = autowireMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the autowire mode for test properties set by Dependency Injection.
|
||||
*/
|
||||
public final int getAutowireMode() {
|
||||
protected final int getAutowireMode() {
|
||||
return this.autowireMode;
|
||||
}
|
||||
|
||||
@@ -153,7 +89,7 @@ public abstract class AbstractDependencyInjectionSpringContextTests extends Abst
|
||||
* <p>The default is {@code true}, meaning that tests cannot be run
|
||||
* unless all properties are populated.
|
||||
*/
|
||||
public final void setDependencyCheck(final boolean dependencyCheck) {
|
||||
protected final void setDependencyCheck(final boolean dependencyCheck) {
|
||||
this.dependencyCheck = dependencyCheck;
|
||||
}
|
||||
|
||||
@@ -161,13 +97,12 @@ public abstract class AbstractDependencyInjectionSpringContextTests extends Abst
|
||||
* Return whether or not dependency checking should be performed for test
|
||||
* properties set by Dependency Injection.
|
||||
*/
|
||||
public final boolean isDependencyCheck() {
|
||||
protected final boolean isDependencyCheck() {
|
||||
return this.dependencyCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare this test instance, injecting dependencies into its protected
|
||||
* fields and its bean properties.
|
||||
* Prepare this test instance, injecting dependencies into its bean properties.
|
||||
* <p>Note: if the {@link ApplicationContext} for this test instance has not
|
||||
* been configured (e.g., is {@code null}), dependency injection
|
||||
* will naturally <strong>not</strong> be performed, but an informational
|
||||
@@ -183,112 +118,10 @@ public abstract class AbstractDependencyInjectionSpringContextTests extends Abst
|
||||
}
|
||||
}
|
||||
else {
|
||||
injectDependencies();
|
||||
}
|
||||
}
|
||||
Assert.state(getApplicationContext() != null,
|
||||
"injectDependencies() called without first configuring an ApplicationContext");
|
||||
|
||||
/**
|
||||
* Inject dependencies into 'this' instance (that is, this test instance).
|
||||
* <p>The default implementation populates protected variables if the
|
||||
* {@link #populateProtectedVariables() appropriate flag is set}, else uses
|
||||
* autowiring if autowiring is switched on (which it is by default).
|
||||
* <p>Override this method if you need full control over how dependencies are
|
||||
* injected into the test instance.
|
||||
* @throws Exception in case of dependency injection failure
|
||||
* @throws IllegalStateException if the {@link ApplicationContext} for this
|
||||
* test instance has not been configured
|
||||
* @see #populateProtectedVariables()
|
||||
*/
|
||||
protected void injectDependencies() throws Exception {
|
||||
Assert.state(getApplicationContext() != null,
|
||||
"injectDependencies() called without first configuring an ApplicationContext");
|
||||
if (isPopulateProtectedVariables()) {
|
||||
if (this.managedVariableNames == null) {
|
||||
initManagedVariableNames();
|
||||
}
|
||||
populateProtectedVariables();
|
||||
}
|
||||
getApplicationContext().getBeanFactory().autowireBeanProperties(this, getAutowireMode(), isDependencyCheck());
|
||||
}
|
||||
|
||||
private void initManagedVariableNames() throws IllegalAccessException {
|
||||
List<String> managedVarNames = new LinkedList<>();
|
||||
Class<?> clazz = getClass();
|
||||
do {
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Found " + fields.length + " fields on " + clazz);
|
||||
}
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
field.setAccessible(true);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Candidate field: " + field);
|
||||
}
|
||||
if (isProtectedInstanceField(field)) {
|
||||
Object oldValue = field.get(this);
|
||||
if (oldValue == null) {
|
||||
managedVarNames.add(field.getName());
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Added managed variable '" + field.getName() + "'");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Rejected managed variable '" + field.getName() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
} while (!clazz.equals(AbstractDependencyInjectionSpringContextTests.class));
|
||||
|
||||
this.managedVariableNames = managedVarNames.toArray(new String[managedVarNames.size()]);
|
||||
}
|
||||
|
||||
private boolean isProtectedInstanceField(Field field) {
|
||||
int modifiers = field.getModifiers();
|
||||
return !Modifier.isStatic(modifiers) && Modifier.isProtected(modifiers);
|
||||
}
|
||||
|
||||
private void populateProtectedVariables() throws IllegalAccessException {
|
||||
for (int i = 0; i < this.managedVariableNames.length; i++) {
|
||||
String varName = this.managedVariableNames[i];
|
||||
Object bean = null;
|
||||
try {
|
||||
Field field = findField(getClass(), varName);
|
||||
bean = getApplicationContext().getBean(varName, field.getType());
|
||||
field.setAccessible(true);
|
||||
field.set(this, bean);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Populated field: " + field);
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("No field with name '" + varName + "'");
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("No bean with name '" + varName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Field findField(Class<?> clazz, String name) throws NoSuchFieldException {
|
||||
try {
|
||||
return clazz.getDeclaredField(name);
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
Class<?> superclass = clazz.getSuperclass();
|
||||
if (superclass != AbstractSpringContextTests.class) {
|
||||
return findField(superclass, name);
|
||||
}
|
||||
else {
|
||||
throw ex;
|
||||
}
|
||||
getApplicationContext().getBeanFactory().autowireBeanProperties(this, getAutowireMode(), isDependencyCheck());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -28,44 +29,30 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* This class is only used within tests in the spring-orm module.
|
||||
*
|
||||
* <p>
|
||||
* Abstract JUnit 3.8 test class that holds and exposes a single Spring
|
||||
* <p>Abstract JUnit 3.8 test class that holds and exposes a single Spring
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class will cache contexts based on a <i>context key</i>: normally the
|
||||
*
|
||||
* <p>This class will cache contexts based on a <i>context key</i>: normally the
|
||||
* config locations String array describing the Spring resource descriptors
|
||||
* making up the context. Unless the {@link #setDirty()} method is called by a
|
||||
* test, the context will not be reloaded, even across different subclasses of
|
||||
* this test. This is particularly beneficial if your context is slow to
|
||||
* construct, for example if you are using Hibernate and the time taken to load
|
||||
* the mappings is an issue.
|
||||
* </p>
|
||||
* <p>
|
||||
* For such standard usage, simply override the {@link #getConfigLocations()}
|
||||
*
|
||||
* <p>For such standard usage, simply override the {@link #getConfigLocations()}
|
||||
* method and provide the desired config files. For alternative configuration
|
||||
* options, see {@link #getConfigPath()} and {@link #getConfigPaths()}.
|
||||
* </p>
|
||||
* <p>
|
||||
* If you don't want to load a standard context from an array of config
|
||||
* locations, you can override the {@link #contextKey()} method. In conjunction
|
||||
* with this you typically need to override the {@link #loadContext(Object)}
|
||||
* method, which by default loads the locations specified in the
|
||||
* {@link #getConfigLocations()} method.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>WARNING:</b> When doing integration tests from within Eclipse, only use
|
||||
* options, see {@link #getConfigPaths()}.
|
||||
*
|
||||
* <p><b>WARNING:</b> When doing integration tests from within Eclipse, only use
|
||||
* classpath resource URLs. Else, you may see misleading failures when changing
|
||||
* context locations.
|
||||
* </p>
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see #getConfigLocations()
|
||||
* @see #contextKey()
|
||||
* @see #loadContext(Object)
|
||||
* @see #getApplicationContext()
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
@@ -73,26 +60,11 @@ import org.springframework.util.StringUtils;
|
||||
@Deprecated
|
||||
abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTests {
|
||||
|
||||
private static final String SLASH = "/";
|
||||
|
||||
/** Application context this test will run against */
|
||||
protected ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private int loadCount = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractSingleSpringContextTests.
|
||||
*/
|
||||
public AbstractSingleSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractSingleSpringContextTests with a JUnit name.
|
||||
* @param name the name of this text fixture
|
||||
*/
|
||||
public AbstractSingleSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation is final. Override {@code onSetUp} for custom behavior.
|
||||
* @see #onSetUp()
|
||||
@@ -101,7 +73,7 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
protected final void setUp() throws Exception {
|
||||
// lazy load, in case getApplicationContext() has not yet been called.
|
||||
if (this.applicationContext == null) {
|
||||
this.applicationContext = getContext(contextKey());
|
||||
this.applicationContext = getContext(getConfigLocations());
|
||||
}
|
||||
prepareTestInstance();
|
||||
onSetUp();
|
||||
@@ -125,15 +97,6 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
protected void onSetUp() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to say that the "applicationContext" instance variable is dirty
|
||||
* and should be reloaded. We need to do this if a test has modified the
|
||||
* context (for example, by replacing a bean definition).
|
||||
*/
|
||||
protected void setDirty() {
|
||||
setDirty(contextKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation is final. Override {@code onTearDown} for
|
||||
* custom behavior.
|
||||
@@ -151,32 +114,6 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
protected void onTearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a key for this context. Default is the config location array as
|
||||
* determined by {@link #getConfigLocations()}.
|
||||
* <p>If you override this method, you will typically have to override
|
||||
* {@link #loadContext(Object)} as well, being able to handle the key type
|
||||
* that this method returns.
|
||||
* @return the context key
|
||||
* @see #getConfigLocations()
|
||||
*/
|
||||
protected Object contextKey() {
|
||||
return getConfigLocations();
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation assumes a key of type String array and loads a
|
||||
* context from the given locations.
|
||||
* <p>If you override {@link #contextKey()}, you will typically have to
|
||||
* override this method as well, being able to handle the key type that
|
||||
* {@code contextKey()} returns.
|
||||
* @see #getConfigLocations()
|
||||
*/
|
||||
@Override
|
||||
protected ConfigurableApplicationContext loadContext(Object key) throws Exception {
|
||||
return loadContextLocations((String[]) key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Spring ApplicationContext from the given config locations.
|
||||
* <p>The default implementation creates a standard
|
||||
@@ -189,8 +126,8 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
* @throws Exception if context loading failed
|
||||
* @see #createApplicationContext(String[])
|
||||
*/
|
||||
protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception {
|
||||
++this.loadCount;
|
||||
@Override
|
||||
protected ConfigurableApplicationContext loadContext(String... locations) throws Exception {
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations));
|
||||
}
|
||||
@@ -209,69 +146,21 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
* @param locations the config locations (as Spring resource locations,
|
||||
* e.g. full classpath locations or any kind of URL)
|
||||
* @return the GenericApplicationContext instance
|
||||
* @see #loadContextLocations(String[])
|
||||
* @see #loadContext(String...)
|
||||
* @see #customizeBeanFactory(DefaultListableBeanFactory)
|
||||
* @see #createBeanDefinitionReader(GenericApplicationContext)
|
||||
*/
|
||||
protected ConfigurableApplicationContext createApplicationContext(String[] locations) {
|
||||
private ConfigurableApplicationContext createApplicationContext(String... locations) {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
prepareApplicationContext(context);
|
||||
customizeBeanFactory(context.getDefaultListableBeanFactory());
|
||||
createBeanDefinitionReader(context).loadBeanDefinitions(locations);
|
||||
new XmlBeanDefinitionReader(context).loadBeanDefinitions(locations);
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the GenericApplicationContext used by this test.
|
||||
* Called before bean definitions are read.
|
||||
* <p>The default implementation is empty. Can be overridden in subclasses to
|
||||
* customize GenericApplicationContext's standard settings.
|
||||
* @param context the context for which the BeanDefinitionReader should be created
|
||||
* @see #createApplicationContext
|
||||
* @see org.springframework.context.support.GenericApplicationContext#setResourceLoader
|
||||
* @see org.springframework.context.support.GenericApplicationContext#setId
|
||||
*/
|
||||
protected void prepareApplicationContext(GenericApplicationContext context) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the internal bean factory of the ApplicationContext used by
|
||||
* this test. Called before bean definitions are read.
|
||||
* <p>The default implementation is empty. Can be overridden in subclasses to
|
||||
* customize DefaultListableBeanFactory's standard settings.
|
||||
* @param beanFactory the newly created bean factory for this context
|
||||
* @see #loadContextLocations
|
||||
* @see #createApplicationContext
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
|
||||
*/
|
||||
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating new {@link BeanDefinitionReader}s for
|
||||
* loading bean definitions into the supplied
|
||||
* {@link GenericApplicationContext context}.
|
||||
* <p>The default implementation creates a new {@link XmlBeanDefinitionReader}.
|
||||
* Can be overridden in subclasses to provide a different
|
||||
* BeanDefinitionReader implementation.
|
||||
* @param context the context for which the BeanDefinitionReader should be created
|
||||
* @return a BeanDefinitionReader for the supplied context
|
||||
* @see #createApplicationContext(String[])
|
||||
* @see BeanDefinitionReader
|
||||
* @see XmlBeanDefinitionReader
|
||||
*/
|
||||
protected BeanDefinitionReader createBeanDefinitionReader(GenericApplicationContext context) {
|
||||
return new XmlBeanDefinitionReader(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to return the locations of their
|
||||
* config files, unless they override {@link #contextKey()} and
|
||||
* {@link #loadContext(Object)} instead.
|
||||
* config files.
|
||||
* <p>A plain path will be treated as class path location, e.g.:
|
||||
* "org/springframework/whatever/foo.xml". Note however that you may prefix
|
||||
* path locations with standard Spring resource prefixes. Therefore, a
|
||||
@@ -285,65 +174,47 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
* @see #getConfigPaths()
|
||||
* @see org.springframework.core.io.ResourceLoader#getResource(String)
|
||||
*/
|
||||
protected String[] getConfigLocations() {
|
||||
protected final String[] getConfigLocations() {
|
||||
String[] paths = getConfigPaths();
|
||||
String[] locations = new String[paths.length];
|
||||
String[] convertedPaths = new String[paths.length];
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
String path = paths[i];
|
||||
if (path.startsWith("/")) {
|
||||
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
|
||||
if (path.startsWith(SLASH)) {
|
||||
convertedPaths[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
|
||||
}
|
||||
else if (!ResourcePatternUtils.isUrl(path)) {
|
||||
convertedPaths[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH
|
||||
+ StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + SLASH + path);
|
||||
}
|
||||
else {
|
||||
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX +
|
||||
StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path);
|
||||
convertedPaths[i] = StringUtils.cleanPath(path);
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
return convertedPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to return paths to their config
|
||||
* Subclasses must override this method to return paths to their config
|
||||
* files, relative to the concrete test class.
|
||||
* <p>A plain path, e.g. "context.xml", will be loaded as classpath resource
|
||||
* from the same package that the concrete test class is defined in. A path
|
||||
* starting with a slash is treated as fully qualified class path location,
|
||||
* e.g.: "/org/springframework/whatever/foo.xml".
|
||||
* <p>The default implementation builds an array for the config path specified
|
||||
* through {@link #getConfigPath()}.
|
||||
* <p>The default implementation returns an empty array.
|
||||
* @return an array of config locations
|
||||
* @see #getConfigPath()
|
||||
* @see java.lang.Class#getResource(String)
|
||||
*/
|
||||
protected String[] getConfigPaths() {
|
||||
String path = getConfigPath();
|
||||
return (path != null ? new String[] { path } : new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to return a single path to a config
|
||||
* file, relative to the concrete test class.
|
||||
* <p>A plain path, e.g. "context.xml", will be loaded as classpath resource
|
||||
* from the same package that the concrete test class is defined in. A path
|
||||
* starting with a slash is treated as fully qualified class path location,
|
||||
* e.g.: "/org/springframework/whatever/foo.xml".
|
||||
* <p>The default implementation simply returns {@code null}.
|
||||
* @return an array of config locations
|
||||
* @see #getConfigPath()
|
||||
* @see Class#getResource(String)
|
||||
*/
|
||||
protected String getConfigPath() {
|
||||
return null;
|
||||
}
|
||||
protected abstract String[] getConfigPaths();
|
||||
|
||||
/**
|
||||
* Return the ApplicationContext that this base class manages; may be
|
||||
* {@code null}.
|
||||
*/
|
||||
public final ConfigurableApplicationContext getApplicationContext() {
|
||||
protected final ConfigurableApplicationContext getApplicationContext() {
|
||||
// lazy load, in case setUp() has not yet been called.
|
||||
if (this.applicationContext == null) {
|
||||
try {
|
||||
this.applicationContext = getContext(contextKey());
|
||||
this.applicationContext = getContext(getConfigLocations());
|
||||
}
|
||||
catch (Exception e) {
|
||||
// log and continue...
|
||||
@@ -357,11 +228,4 @@ abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTes
|
||||
return this.applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current number of context load attempts.
|
||||
*/
|
||||
public final int getLoadCount() {
|
||||
return this.loadCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,39 +27,29 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* This class is only used within tests in the spring-orm module.
|
||||
*
|
||||
* <p>
|
||||
* Superclass for JUnit 3.8 test cases using Spring
|
||||
* <p>Superclass for JUnit 3.8 test cases using Spring
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContexts}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Maintains a static cache of contexts by key. This has significant performance
|
||||
*
|
||||
* <p>Maintains a static cache of contexts by key. This has significant performance
|
||||
* benefit if initializing the context would take time. While initializing a
|
||||
* Spring context itself is very quick, some beans in a context, such as a
|
||||
* LocalSessionFactoryBean for working with Hibernate, may take some time to
|
||||
* initialize. Hence it often makes sense to do that initializing once.
|
||||
* </p>
|
||||
* <p>
|
||||
* Any ApplicationContext created by this class will be asked to register a JVM
|
||||
*
|
||||
* <p>Any ApplicationContext created by this class will be asked to register a JVM
|
||||
* shutdown hook for itself. Unless the context gets closed early, all context
|
||||
* instances will be automatically closed on JVM shutdown. This allows for
|
||||
* freeing external resources held by beans within the context, e.g. temporary
|
||||
* files.
|
||||
* </p>
|
||||
* <p>
|
||||
* Normally you won't extend this class directly but rather one of its
|
||||
* subclasses.
|
||||
* </p>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 1.1.1
|
||||
* @see #isDisabledInThisEnvironment
|
||||
* @see AbstractSingleSpringContextTests
|
||||
* @see AbstractDependencyInjectionSpringContextTests
|
||||
* @see AbstractTransactionalSpringContextTests
|
||||
@@ -70,146 +60,46 @@ import org.springframework.util.StringUtils;
|
||||
@Deprecated
|
||||
abstract class AbstractSpringContextTests extends TestCase {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Map of context keys returned by subclasses of this class, to Spring
|
||||
* contexts. This needs to be static, as JUnit tests are destroyed and
|
||||
* recreated between running individual test methods.
|
||||
*/
|
||||
private static Map<String, ConfigurableApplicationContext> contextKeyToContextMap =
|
||||
new HashMap<String, ConfigurableApplicationContext>();
|
||||
|
||||
private static int disabledTestCount;
|
||||
|
||||
/**
|
||||
* Return the number of tests disabled in this environment.
|
||||
*/
|
||||
public static int getDisabledTestCount() {
|
||||
return disabledTestCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractSpringContextTests.
|
||||
*/
|
||||
public AbstractSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractSpringContextTests with a JUnit name.
|
||||
*/
|
||||
public AbstractSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
// getName will return the name of the method being run
|
||||
if (isDisabledInThisEnvironment(getName())) {
|
||||
recordDisabled();
|
||||
this.logger.info("**** " + getClass().getName() + "." + getName()
|
||||
+ " is disabled in this environment: " + "Total disabled tests = "
|
||||
+ getDisabledTestCount());
|
||||
return;
|
||||
}
|
||||
|
||||
// Let JUnit handle execution
|
||||
super.runBare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this test run?
|
||||
*
|
||||
* @param testMethodName name of the test method
|
||||
* @return whether the test should execute in the current environment
|
||||
*/
|
||||
protected boolean isDisabledInThisEnvironment(String testMethodName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a disabled test.
|
||||
*
|
||||
* @return the current disabled test count
|
||||
*/
|
||||
protected int recordDisabled() {
|
||||
return ++disabledTestCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly add an ApplicationContext instance under a given key.
|
||||
* <p>This is not meant to be used by subclasses. It is rather exposed for
|
||||
* special test suite environments.
|
||||
* @param key the context key
|
||||
* @param locations the context key
|
||||
* @param context the ApplicationContext instance
|
||||
*/
|
||||
public final void addContext(Object key, ConfigurableApplicationContext context) {
|
||||
public final void addContext(String[] locations, ConfigurableApplicationContext context) {
|
||||
Assert.notNull(context, "ApplicationContext must not be null");
|
||||
contextKeyToContextMap.put(contextKeyString(key), context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether there is a cached context for the given key.
|
||||
* @param key the context key
|
||||
*/
|
||||
protected final boolean hasCachedContext(Object key) {
|
||||
return contextKeyToContextMap.containsKey(contextKeyString(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied context {@code key} is <em>empty</em>.
|
||||
* <p>By default, {@code null} values, empty strings, and zero-length
|
||||
* arrays are considered <em>empty</em>.
|
||||
* @param key the context key to check
|
||||
* @return {@code true} if the supplied context key is empty
|
||||
*/
|
||||
protected boolean isContextKeyEmpty(Object key) {
|
||||
return (key == null) || ((key instanceof String) && !StringUtils.hasText((String) key)) ||
|
||||
((key instanceof Object[]) && ObjectUtils.isEmpty((Object[]) key));
|
||||
contextKeyToContextMap.put(contextKey(locations), context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an ApplicationContext for the given key, potentially cached.
|
||||
* @param key the context key; may be {@code null}.
|
||||
* @param locations the context key; may be {@code null}.
|
||||
* @return the corresponding ApplicationContext instance (potentially cached),
|
||||
* or {@code null} if the provided {@code key} is <em>empty</em>
|
||||
*/
|
||||
protected final ConfigurableApplicationContext getContext(Object key) throws Exception {
|
||||
if (isContextKeyEmpty(key)) {
|
||||
protected final ConfigurableApplicationContext getContext(String... locations) throws Exception {
|
||||
if (ObjectUtils.isEmpty(locations)) {
|
||||
return null;
|
||||
}
|
||||
String keyString = contextKeyString(key);
|
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.get(keyString);
|
||||
String key = contextKey(locations);
|
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.get(key);
|
||||
if (ctx == null) {
|
||||
ctx = loadContext(key);
|
||||
ctx = loadContext(locations);
|
||||
ctx.registerShutdownHook();
|
||||
contextKeyToContextMap.put(keyString, ctx);
|
||||
contextKeyToContextMap.put(key, ctx);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the context with the given key as dirty. This will cause the cached
|
||||
* context to be reloaded before the next test case is executed.
|
||||
* <p>Call this method only if you change the state of a singleton bean,
|
||||
* potentially affecting future tests.
|
||||
*/
|
||||
protected final void setDirty(Object contextKey) {
|
||||
String keyString = contextKeyString(contextKey);
|
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.remove(keyString);
|
||||
if (ctx != null) {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this to return a String representation of their
|
||||
* context key for use in caching and logging.
|
||||
* @param contextKey the context key
|
||||
*/
|
||||
protected String contextKeyString(Object contextKey) {
|
||||
return ObjectUtils.nullSafeToString(contextKey);
|
||||
private final String contextKey(String... locations) {
|
||||
return ObjectUtils.nullSafeToString(locations);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,6 +108,6 @@ abstract class AbstractSpringContextTests extends TestCase {
|
||||
* @param key the context key
|
||||
* @return the corresponding ApplicationContext instance (new)
|
||||
*/
|
||||
protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception;
|
||||
protected abstract ConfigurableApplicationContext loadContext(String... locations) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
|
||||
/**
|
||||
* This class is only used within tests in the spring-orm module.
|
||||
*
|
||||
* <p>Subclass of AbstractTransactionalSpringContextTests that adds some convenience
|
||||
* functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean
|
||||
* to be defined in the Spring application context.
|
||||
*
|
||||
* <p>This class exposes a {@link org.springframework.jdbc.core.JdbcTemplate}
|
||||
* and provides an easy way to delete from the database in a new transaction.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Thomas Risberg
|
||||
* @since 1.1.1
|
||||
* @see #setDataSource(javax.sql.DataSource)
|
||||
* @see #getJdbcTemplate()
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
abstract class AbstractTransactionalDataSourceSpringContextTests extends AbstractTransactionalSpringContextTests {
|
||||
|
||||
protected JdbcTemplate jdbcTemplate;
|
||||
|
||||
private String sqlScriptEncoding;
|
||||
|
||||
/**
|
||||
* Did this test delete any tables? If so, we forbid transaction completion,
|
||||
* and only allow rollback.
|
||||
*/
|
||||
private boolean zappedTables;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractTransactionalDataSourceSpringContextTests.
|
||||
*/
|
||||
public AbstractTransactionalDataSourceSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractTransactionalDataSourceSpringContextTests with a JUnit name.
|
||||
*/
|
||||
public AbstractTransactionalDataSourceSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter: DataSource is provided by Dependency Injection.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JdbcTemplate that this base class manages.
|
||||
*/
|
||||
public final JdbcTemplate getJdbcTemplate() {
|
||||
return this.jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the encoding for SQL scripts, if different from the platform encoding.
|
||||
* @see #executeSqlScript
|
||||
*/
|
||||
public void setSqlScriptEncoding(String sqlScriptEncoding) {
|
||||
this.sqlScriptEncoding = sqlScriptEncoding;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenient method to delete all rows from these tables.
|
||||
* Calling this method will make avoidance of rollback by calling
|
||||
* {@code setComplete()} impossible.
|
||||
* @see #setComplete
|
||||
*/
|
||||
protected void deleteFromTables(String... names) {
|
||||
for (String name : names) {
|
||||
int rowCount = this.jdbcTemplate.update("DELETE FROM " + name);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Deleted " + rowCount + " rows from table " + name);
|
||||
}
|
||||
}
|
||||
this.zappedTables = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to prevent the transaction committing if a number of tables have been
|
||||
* cleared, as a defensive measure against accidental <i>permanent</i> wiping of a database.
|
||||
* @see org.springframework.test.AbstractTransactionalSpringContextTests#setComplete()
|
||||
*/
|
||||
@Override
|
||||
protected final void setComplete() {
|
||||
if (this.zappedTables) {
|
||||
throw new IllegalStateException("Cannot set complete after deleting tables");
|
||||
}
|
||||
super.setComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 this.jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + tableName, Integer.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the given SQL script.
|
||||
* <p>Use with caution outside of a transaction!
|
||||
* <p>The script will normally be loaded by classpath.
|
||||
* <p><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
|
||||
* @see ResourceDatabasePopulator
|
||||
* @see #setSqlScriptEncoding
|
||||
*/
|
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||
new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(jdbcTemplate.getDataSource());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,10 +16,20 @@
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
/**
|
||||
@@ -75,15 +85,29 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
* non-transactional capability is provided to enable use of the same subclass
|
||||
* in different environments.
|
||||
*
|
||||
* <p>Adds some convenience functionality for JDBC access. Expects a
|
||||
* {@link javax.sql.DataSource} bean to be defined in the Spring application
|
||||
* context.
|
||||
*
|
||||
* <p>This class exposes a {@link org.springframework.jdbc.core.JdbcTemplate}
|
||||
* and provides an easy way to delete from the database in a new transaction.
|
||||
*
|
||||
* <p>Test methods can be annotated with the regular Spring
|
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
|
||||
* annotation — for example, to force execution in a read-only transaction
|
||||
* or to prevent any transaction from being created at all by setting the propagation
|
||||
* level to {@code NOT_SUPPORTED}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Thomas Risberg
|
||||
* @author Sam Brannen
|
||||
* @since 1.1.1
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
abstract class AbstractTransactionalSpringContextTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
public abstract class AbstractTransactionalSpringContextTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
/** The transaction manager to use */
|
||||
protected PlatformTransactionManager transactionManager;
|
||||
@@ -102,28 +126,31 @@ abstract class AbstractTransactionalSpringContextTests extends AbstractDependenc
|
||||
* DefaultTransactionDefinition. Subclasses can change this to cause
|
||||
* different behavior.
|
||||
*/
|
||||
protected TransactionDefinition transactionDefinition= new DefaultTransactionDefinition();
|
||||
protected TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
|
||||
|
||||
private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
|
||||
|
||||
/**
|
||||
* TransactionStatus for this test. Typical subclasses won't need to use it.
|
||||
*/
|
||||
protected TransactionStatus transactionStatus;
|
||||
protected TransactionStatus transactionStatus;
|
||||
|
||||
protected JdbcTemplate jdbcTemplate;
|
||||
|
||||
/**
|
||||
* Did this test delete any tables? If so, we forbid transaction completion,
|
||||
* and only allow rollback.
|
||||
*/
|
||||
private boolean zappedTables;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractTransactionalSpringContextTests.
|
||||
* Setter: DataSource is provided by Dependency Injection.
|
||||
*/
|
||||
public AbstractTransactionalSpringContextTests() {
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractTransactionalSpringContextTests with a JUnit name.
|
||||
*/
|
||||
public AbstractTransactionalSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the transaction manager to use. No transaction management will be
|
||||
* available if this is not set. Populated through dependency injection by
|
||||
@@ -140,9 +167,10 @@ abstract class AbstractTransactionalSpringContextTests extends AbstractDependenc
|
||||
* Subclasses can set this value in their constructor to change the default,
|
||||
* which is always to roll the transaction back.
|
||||
*/
|
||||
public void setDefaultRollback(final boolean defaultRollback) {
|
||||
protected void setDefaultRollback(final boolean defaultRollback) {
|
||||
this.defaultRollback = defaultRollback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <em>default rollback</em> flag for this test.
|
||||
* @see #setDefaultRollback(boolean)
|
||||
@@ -153,12 +181,17 @@ abstract class AbstractTransactionalSpringContextTests extends AbstractDependenc
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not to rollback transactions for the current test.
|
||||
* <p>The default implementation delegates to {@link #isDefaultRollback()}.
|
||||
* Determine whether or not to roll back transactions for the current test.
|
||||
* <p>The default implementation simply delegates to {@link #isDefaultRollback()}.
|
||||
* Subclasses can override as necessary.
|
||||
* @return the <em>rollback</em> flag for the current test
|
||||
*/
|
||||
protected boolean isRollback() {
|
||||
return isDefaultRollback();
|
||||
boolean rollback = isDefaultRollback();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Using default rollback [" + rollback + "] for test [" + getName() + "].");
|
||||
}
|
||||
return rollback;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,6 +327,49 @@ abstract class AbstractTransactionalSpringContextTests extends AbstractDependenc
|
||||
protected void onTearDownAfterTransaction() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to populate transaction definition from annotations.
|
||||
*/
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
final Method testMethod = getTestMethod();
|
||||
|
||||
TransactionDefinition explicitTransactionDefinition = this.transactionAttributeSource.getTransactionAttribute(
|
||||
testMethod, getClass());
|
||||
if (explicitTransactionDefinition != null) {
|
||||
this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method ["
|
||||
+ getName() + "].");
|
||||
setTransactionDefinition(explicitTransactionDefinition);
|
||||
}
|
||||
|
||||
if (this.transactionDefinition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
|
||||
preventTransaction();
|
||||
}
|
||||
|
||||
super.runBare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current test method.
|
||||
*/
|
||||
protected Method getTestMethod() {
|
||||
assertNotNull("TestCase.getName() cannot be null", getName());
|
||||
Method testMethod = null;
|
||||
try {
|
||||
// Use same algorithm as JUnit itself to retrieve the test method
|
||||
// about to be executed (the method name is returned by getName). It
|
||||
// has to be public so we can retrieve it.
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the transaction to commit for this test method, even if the test
|
||||
* method is configured to {@link #isRollback() rollback}.
|
||||
@@ -304,6 +380,9 @@ abstract class AbstractTransactionalSpringContextTests extends AbstractDependenc
|
||||
if (this.transactionManager == null) {
|
||||
throw new IllegalStateException("No transaction manager set");
|
||||
}
|
||||
if (this.zappedTables) {
|
||||
throw new IllegalStateException("Cannot set complete after deleting tables");
|
||||
}
|
||||
this.complete = true;
|
||||
}
|
||||
|
||||
@@ -360,4 +439,46 @@ abstract class AbstractTransactionalSpringContextTests extends AbstractDependenc
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method to delete all rows from these tables.
|
||||
* Calling this method will make avoidance of rollback by calling
|
||||
* {@code setComplete()} impossible.
|
||||
* @see #setComplete
|
||||
*/
|
||||
protected void deleteFromTables(String... names) {
|
||||
for (String name : names) {
|
||||
int rowCount = this.jdbcTemplate.update("DELETE FROM " + name);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Deleted " + rowCount + " rows from table " + name);
|
||||
}
|
||||
}
|
||||
this.zappedTables = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 this.jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + tableName, Integer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given SQL script.
|
||||
* <p>Use with caution outside of a transaction!
|
||||
* <p>The script will normally be loaded by classpath.
|
||||
* <p><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
|
||||
* @see ResourceDatabasePopulator
|
||||
* @see #setSqlScriptEncoding
|
||||
*/
|
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||
new ResourceDatabasePopulator(continueOnError, false, null, resource).execute(jdbcTemplate.getDataSource());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
@@ -46,7 +45,7 @@ import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
|
||||
import org.springframework.test.AbstractAnnotationAwareTransactionalTests;
|
||||
import org.springframework.test.AbstractTransactionalSpringContextTests;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -84,7 +83,7 @@ import org.springframework.util.StringUtils;
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactionalTests {
|
||||
public abstract class AbstractJpaTests extends AbstractTransactionalSpringContextTests {
|
||||
|
||||
private static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml";
|
||||
|
||||
@@ -141,39 +140,9 @@ public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactio
|
||||
return !InstrumentationLoadTimeWeaver.isInstrumentationAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty() {
|
||||
super.setDirty();
|
||||
contextCache.remove(cacheKeys());
|
||||
classLoaderCache.remove(cacheKeys());
|
||||
|
||||
// If we are a shadow loader, we need to invoke
|
||||
// the shadow parent to set it dirty, as
|
||||
// it is the shadow parent that maintains the cache state,
|
||||
// not the child
|
||||
if (this.shadowParent != null) {
|
||||
try {
|
||||
Method m = shadowParent.getClass().getMethod("setDirty", (Class[]) null);
|
||||
m.invoke(shadowParent, (Object[]) null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
|
||||
// getName will return the name of the method being run.
|
||||
if (isDisabledInThisEnvironment(getName())) {
|
||||
// Let superclass log that we didn't run the test.
|
||||
super.runBare();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shouldUseShadowLoader()) {
|
||||
super.runBare();
|
||||
return;
|
||||
@@ -262,7 +231,7 @@ public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactio
|
||||
|
||||
/* AbstractSpringContextTests.addContext(Object, ApplicationContext) */
|
||||
Class applicationContextClass = shadowingClassLoader.loadClass(ConfigurableApplicationContext.class.getName());
|
||||
Method addContextMethod = shadowedTestClass.getMethod("addContext", Object.class, applicationContextClass);
|
||||
Method addContextMethod = shadowedTestClass.getMethod("addContext", String[].class, applicationContextClass);
|
||||
ReflectionUtils.makeAccessible(addContextMethod);
|
||||
addContextMethod.invoke(shadowedTestCase, configLocations, cachedContext);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user