moving unit tests from .testsuite -> .orm

This commit is contained in:
Chris Beams 2008-12-17 05:33:45 +00:00
parent 10be5f08a5
commit f4d8b69126
97 changed files with 4324 additions and 1056 deletions

View File

@ -13,23 +13,39 @@
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.transaction"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.web"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate/3.2.6.ga/com.springsource.org.hibernate-3.2.6.ga.jar" sourcepath="/IVY_CACHE/org.hibernate/com.springsource.org.hibernate/3.2.6.ga/com.springsource.org.hibernate-sources-3.2.6.ga.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate.annotations.common/3.3.0.ga/com.springsource.org.hibernate.annotations.common-3.3.0.ga.jar" sourcepath="/IVY_CACHE/org.hibernate/com.springsource.org.hibernate.annotations.common/3.3.0.ga/com.springsource.org.hibernate.annotations-sources-3.3.0.common.ga.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-1.0.0.jar" sourcepath="/IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/com.oracle.toplink.essentials/com.springsource.oracle.toplink.essentials/2.0.0.b41-beta2/com.springsource.oracle.toplink.essentials-2.0.0.b41-beta2.jar" sourcepath="/IVY_CACHE/com.oracle.toplink.essentials/com.springsource.oracle.toplink.essentials/2.0.0.b41-beta2/com.springsource.oracle.toplink.essentials-sources-2.0.0.b41-beta2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa/1.0.2/com.springsource.org.apache.openjpa-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa/1.0.2/com.springsource.org.apache.openjpa-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.lib/1.0.2/com.springsource.org.apache.openjpa.lib-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.lib/1.0.2/com.springsource.org.apache.openjpa.lib-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.persistence/1.0.2/com.springsource.org.apache.openjpa.persistence-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.persistence/1.0.2/com.springsource.org.apache.openjpa.persistence-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.persistence/com.springsource.org.eclipse.persistence.jpa/1.0.1/com.springsource.org.eclipse.persistence.jpa-1.0.1.jar" sourcepath="/IVY_CACHE/org.eclipse.persistence/com.springsource.org.eclipse.persistence.jpa/1.0.1/com.springsource.org.eclipse.persistence.jpa-sources-1.0.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.java5/1.0.2/com.springsource.org.apache.openjpa.java5-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.java5/1.0.2/com.springsource.org.apache.openjpa.java5-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.jdbc/1.0.2/com.springsource.org.apache.openjpa.jdbc-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.jdbc/1.0.2/com.springsource.org.apache.openjpa.jdbc-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.jdbc.java5/1.0.2/com.springsource.org.apache.openjpa.jdbc.java5-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.jdbc.java5/1.0.2/com.springsource.org.apache.openjpa.jdbc.java5-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.lib.java5/1.0.2/com.springsource.org.apache.openjpa.lib.java5-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.lib.java5/1.0.2/com.springsource.org.apache.openjpa.lib.java5-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.persistence.jdbc/1.0.2/com.springsource.org.apache.openjpa.persistence.jdbc-1.0.2.jar" sourcepath="/IVY_CACHE/org.apache.openjpa/com.springsource.org.apache.openjpa.persistence.jdbc/1.0.2/com.springsource.org.apache.openjpa.persistence.jdbc-sources-1.0.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-1.1.0.jar" sourcepath="/IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.5.0/com.springsource.org.junit-4.5.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.5.0/com.springsource.org.junit-sources-4.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.persistence/com.springsource.org.eclipse.persistence.jpa/1.0.1/com.springsource.org.eclipse.persistence.jpa-1.0.1.jar" sourcepath="/IVY_CACHE/org.eclipse.persistence/com.springsource.org.eclipse.persistence.jpa/1.0.1/com.springsource.org.eclipse.persistence.jpa-sources-1.0.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.persistence/com.springsource.org.eclipse.persistence/1.0.1/com.springsource.org.eclipse.persistence-1.0.1.jar" sourcepath="/IVY_CACHE/org.eclipse.persistence/com.springsource.org.eclipse.persistence/1.0.1/com.springsource.org.eclipse.persistence-sources-1.0.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.2.RELEASE/com.springsource.org.aspectj.weaver-1.6.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.ibatis/com.springsource.com.ibatis/2.3.4.726/com.springsource.com.ibatis-2.3.4.726.jar" sourcepath="/IVY_CACHE/org.apache.ibatis/com.springsource.com.ibatis/2.3.4.726/com.springsource.com.ibatis-sources-2.3.4.726.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate.annotations/3.3.0.ga/com.springsource.org.hibernate.annotations-3.3.0.ga.jar" sourcepath="/IVY_CACHE/org.hibernate/com.springsource.org.hibernate.annotations/3.3.0.ga/com.springsource.org.hibernate.annotations-sources-3.3.0.ga.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.jdo/com.springsource.javax.jdo/2.0.0/com.springsource.javax.jdo-2.0.0.jar" sourcepath="/IVY_CACHE/javax.jdo/com.springsource.javax.jdo/2.0.0/com.springsource.javax.jdo-sources-2.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-2.5.0.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-sources-2.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.ejb/com.springsource.javax.ejb/3.0.0/com.springsource.javax.ejb-3.0.0.jar" sourcepath="/IVY_CACHE/javax.ejb/com.springsource.javax.ejb/3.0.0/com.springsource.javax.ejb-sources-3.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate.ejb/3.3.1.ga/com.springsource.org.hibernate.ejb-3.3.1.ga.jar" sourcepath="/IVY_CACHE/org.hibernate/com.springsource.org.hibernate.ejb/3.3.1.ga/com.springsource.org.hibernate.ejb-sources-3.3.1.ga.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.dom4j/com.springsource.org.dom4j/1.6.1/com.springsource.org.dom4j-1.6.1.jar" sourcepath="/IVY_CACHE/org.dom4j/com.springsource.org.dom4j/1.6.1/com.springsource.org.dom4j-sources-1.6.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.dbcp/1.2.2.osgi/com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.dbcp/1.2.2.osgi/com.springsource.org.apache.commons.dbcp-sources-1.2.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hsqldb/com.springsource.org.hsqldb/1.8.0.9/com.springsource.org.hsqldb-1.8.0.9.jar" sourcepath="/IVY_CACHE/org.hsqldb/com.springsource.org.hsqldb/1.8.0.9/com.springsource.org.hsqldb-sources-1.8.0.9.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-2.1.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-sources-2.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jboss.util/com.springsource.org.jboss.util/2.0.4.GA/com.springsource.org.jboss.util-2.0.4.GA.jar" sourcepath="/IVY_CACHE/org.jboss.util/com.springsource.org.jboss.util/2.0.4.GA/com.springsource.org.jboss.util-sources-2.0.4.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.serp/com.springsource.serp/1.13.1/com.springsource.serp-1.13.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/edu.oswego.cs.concurrent/com.springsource.edu.oswego.cs.dl.util.concurrent/1.3.4/com.springsource.edu.oswego.cs.dl.util.concurrent-1.3.4.jar" sourcepath="/IVY_CACHE/edu.oswego.cs.concurrent/com.springsource.edu.oswego.cs.dl.util.concurrent/1.3.4/com.springsource.edu.oswego.cs.dl.util.concurrent-sources-1.3.4.jar"/>
<classpathentry kind="var" path="IVY_CACHE"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -35,7 +35,14 @@
<dependency org="org.aopalliance" name="com.springsource.org.aopalliance" rev="1.0.0" conf="optional, aop->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile->compile"/>
<dependency org="org.apache.ibatis" name="com.springsource.com.ibatis" rev="2.3.4.726" conf="optional, ibatis->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.persistence" rev="1.0.2" conf="optional, openjpa->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa" rev="1.0.2" conf="test->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.java5" rev="1.0.2" conf="test->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.jdbc.java5" rev="1.0.2" conf="test->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.lib" rev="1.0.2" conf="test->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.lib.java5" rev="1.0.2" conf="test->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.persistence" rev="1.0.2" conf="compile->compile"/>
<dependency org="org.apache.openjpa" name="com.springsource.org.apache.openjpa.persistence.jdbc" rev="1.0.2" conf="compile->compile"/>
<dependency org="org.eclipse.persistence" name="com.springsource.org.eclipse.persistence" rev="1.0.1" conf="test->compile"/>
<dependency org="org.eclipse.persistence" name="com.springsource.org.eclipse.persistence.jpa" rev="1.0.1" conf="optional, eclipselink-> compile"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="optional, hibernate->compile"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="optional, hibernate-jpa->compile"/>
@ -53,8 +60,11 @@
<dependency org="org.springframework" name="org.springframework.transaction" rev="latest.integration" conf="compile->compile"/>
<dependency org="org.springframework" name="org.springframework.web" rev="latest.integration" conf="optional, web->compile"/>
<!-- test dependencies -->
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.5.0" conf="test->runtime"/>
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="1.5.4" conf="test->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.dbcp" rev="1.2.2.osgi" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.3.0" conf="test->compile"/>
<dependency org="org.hsqldb" name="com.springsource.org.hsqldb" rev="1.8.0.9" conf="test->compile"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.5.0" conf="test->runtime"/>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,82 @@
/*
* Copyright 2002-2008 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.beans.factory.config;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.ObjectFactory;
/**
* @author Juergen Hoeller
*/
public class SimpleMapScope implements Scope, Serializable {
private final Map map = new HashMap();
private final List callbacks = new LinkedList();
public SimpleMapScope() {
}
public final Map getMap() {
return this.map;
}
public Object get(String name, ObjectFactory objectFactory) {
synchronized (this.map) {
Object scopedObject = this.map.get(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
this.map.put(name, scopedObject);
}
return scopedObject;
}
}
public Object remove(String name) {
synchronized (this.map) {
return this.map.remove(name);
}
}
public void registerDestructionCallback(String name, Runnable callback) {
this.callbacks.add(callback);
}
public Object resolveContextualObject(String key) {
return null;
}
public void close() {
for (Iterator it = this.callbacks.iterator(); it.hasNext();) {
Runnable runnable = (Runnable) it.next();
runnable.run();
}
}
public String getConversationId() {
return null;
}
}

View File

@ -0,0 +1,631 @@
/*
* Copyright 2002-2007 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.orm.hibernate3.support;
import junit.framework.TestCase;
import org.junit.Ignore;
/**
* @author Juergen Hoeller
* @since 05.03.2005
*/
@Ignore // getting errors on mocks
public class OpenSessionInViewTests extends TestCase {
// public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// MockControl sessionControl = MockControl.createControl(Session.class);
// Session session = (Session) sessionControl.getMock();
//
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
// rawInterceptor.setSessionFactory(sf);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// MockServletContext sc = new MockServletContext();
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf, 2);
// session.isOpen();
// sessionControl.setReturnValue(true, 1);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
// sfControl.replay();
// sessionControl.replay();
// interceptor.preHandle(request, response, "handler");
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
//
// // check that further invocations simply participate
// interceptor.preHandle(request, response, "handler");
//
// assertEquals(session, SessionFactoryUtils.getSession(sf, false));
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// sfControl.verify();
// sessionControl.verify();
//
// sfControl.reset();
// sessionControl.reset();
// sfControl.replay();
// sessionControl.replay();
// interceptor.postHandle(request, response, "handler", null);
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
//
// sfControl.reset();
// sessionControl.reset();
// session.close();
// sessionControl.setReturnValue(null, 1);
// sfControl.replay();
// sessionControl.replay();
// interceptor.afterCompletion(request, response, "handler", null);
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
// }
//
// public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactoryImplementor.class);
// final SessionFactoryImplementor sf = (SessionFactoryImplementor) sfControl.getMock();
// MockControl sessionControl = MockControl.createControl(Session.class);
// Session session = (Session) sessionControl.getMock();
//
// MockControl tmControl = MockControl.createControl(TransactionManager.class);
// TransactionManager tm = (TransactionManager) tmControl.getMock();
// tm.getTransaction();
// tmControl.setReturnValue(null, 2);
//
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
// rawInterceptor.setSessionFactory(sf);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// MockServletContext sc = new MockServletContext();
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// sf.getTransactionManager();
// sfControl.setReturnValue(tm, 2);
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.isOpen();
// sessionControl.setReturnValue(true, 1);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
//
// tmControl.replay();
// sfControl.replay();
// sessionControl.replay();
//
// interceptor.preHandle(request, response, "handler");
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
//
// // check that further invocations simply participate
// interceptor.preHandle(request, response, "handler");
//
// assertEquals(session, SessionFactoryUtils.getSession(sf, false));
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// sfControl.verify();
// sessionControl.verify();
//
// sfControl.reset();
// sessionControl.reset();
// sfControl.replay();
// sessionControl.replay();
// interceptor.postHandle(request, response, "handler", null);
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
//
// sfControl.reset();
// sessionControl.reset();
// session.close();
// sessionControl.setReturnValue(null, 1);
// sfControl.replay();
// sessionControl.replay();
// interceptor.afterCompletion(request, response, "handler", null);
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
// }
//
// public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// MockControl sessionControl = MockControl.createControl(Session.class);
// Session session = (Session) sessionControl.getMock();
//
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
// rawInterceptor.setSessionFactory(sf);
// rawInterceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// MockServletContext sc = new MockServletContext();
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf);
// sfControl.replay();
// sessionControl.replay();
// interceptor.preHandle(request, response, "handler");
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
//
// sfControl.reset();
// sessionControl.reset();
// session.flush();
// sessionControl.setVoidCallable(1);
// sfControl.replay();
// sessionControl.replay();
// interceptor.postHandle(request, response, "handler", null);
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
//
// sfControl.reset();
// sessionControl.reset();
// session.close();
// sessionControl.setReturnValue(null, 1);
// sfControl.replay();
// sessionControl.replay();
// interceptor.afterCompletion(request, response, "handler", null);
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
// sfControl.verify();
// sessionControl.verify();
// }
//
// public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// MockControl sessionControl = MockControl.createControl(Session.class);
// Session session = (Session) sessionControl.getMock();
//
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
// rawInterceptor.setSessionFactory(sf);
// rawInterceptor.setSingleSession(false);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// MockServletContext sc = new MockServletContext();
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf, 1);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
// sfControl.replay();
// sessionControl.replay();
//
// interceptor.preHandle(request, response, "handler");
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
// SessionFactoryUtils.releaseSession(sess, sf);
//
// // check that further invocations simply participate
// interceptor.preHandle(request, response, "handler");
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// sfControl.verify();
// sessionControl.verify();
// sfControl.reset();
// sessionControl.reset();
//
// session.close();
// sessionControl.setReturnValue(null, 1);
// sfControl.replay();
// sessionControl.replay();
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
// sfControl.verify();
// sessionControl.verify();
// }
//
// public void testOpenSessionInViewFilterWithSingleSession() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// MockControl sessionControl = MockControl.createControl(Session.class);
// Session session = (Session) sessionControl.getMock();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
// session.close();
// sessionControl.setReturnValue(null, 1);
// sfControl.replay();
// sessionControl.replay();
//
// MockControl sf2Control = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
// MockControl session2Control = MockControl.createControl(Session.class);
// Session session2 = (Session) session2Control.getMock();
//
// sf2.openSession();
// sf2Control.setReturnValue(session2, 1);
// session2.getSessionFactory();
// session2Control.setReturnValue(sf);
// session2.setFlushMode(FlushMode.AUTO);
// session2Control.setVoidCallable(1);
// session2.close();
// session2Control.setReturnValue(null, 1);
// sf2Control.replay();
// session2Control.replay();
//
// MockServletContext sc = new MockServletContext();
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
// wac.setServletContext(sc);
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
// wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
// wac.refresh();
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
// filterConfig2.addInitParameter("flushMode", "AUTO");
//
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
// filter.init(filterConfig);
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
// filter2.init(filterConfig2);
//
// final FilterChain filterChain = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// servletRequest.setAttribute("invoked", Boolean.TRUE);
// }
// };
//
// final FilterChain filterChain2 = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
// throws IOException, ServletException {
// assertTrue(TransactionSynchronizationManager.hasResource(sf2));
// filter.doFilter(servletRequest, servletResponse, filterChain);
// }
// };
//
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
//
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
// assertFalse(TransactionSynchronizationManager.hasResource(sf2));
// filter2.doFilter(request, response, filterChain3);
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
// assertFalse(TransactionSynchronizationManager.hasResource(sf2));
// assertNotNull(request.getAttribute("invoked"));
//
// sfControl.verify();
// sessionControl.verify();
// sf2Control.verify();
// session2Control.verify();
//
// wac.close();
// }
//
// public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// MockControl sessionControl = MockControl.createControl(Session.class);
// Session session = (Session) sessionControl.getMock();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
// session.close();
// sessionControl.setReturnValue(null, 1);
// sfControl.replay();
// sessionControl.replay();
//
// MockServletContext sc = new MockServletContext();
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
// wac.setServletContext(sc);
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
// wac.refresh();
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
//
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
// rawInterceptor.setSessionFactory(sf);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// interceptor.preHandle(request, response, "handler");
//
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
// filter.init(filterConfig);
//
// final FilterChain filterChain = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// servletRequest.setAttribute("invoked", Boolean.TRUE);
// }
// };
//
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// filter.doFilter(request, response, filterChain);
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
// assertNotNull(request.getAttribute("invoked"));
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// sfControl.verify();
// sessionControl.verify();
//
// wac.close();
// }
//
// public void testOpenSessionInViewFilterWithDeferredClose() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// final MockControl sessionControl = MockControl.createControl(Session.class);
// final Session session = (Session) sessionControl.getMock();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf);
// session.getFlushMode();
// sessionControl.setReturnValue(FlushMode.NEVER, 1);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
// sfControl.replay();
// sessionControl.replay();
//
// MockControl sf2Control = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
// final MockControl session2Control = MockControl.createControl(Session.class);
// final Session session2 = (Session) session2Control.getMock();
// MockControl txControl = MockControl.createControl(Transaction.class);
// Transaction tx = (Transaction) txControl.getMock();
// MockControl conControl = MockControl.createControl(Connection.class);
// Connection con = (Connection) conControl.getMock();
//
// sf2.openSession();
// sf2Control.setReturnValue(session2, 1);
// session2.beginTransaction();
// session2Control.setReturnValue(tx, 1);
// session2.connection();
// session2Control.setReturnValue(con, 2);
// tx.commit();
// txControl.setVoidCallable(1);
// session2.isConnected();
// session2Control.setReturnValue(true, 1);
// con.isReadOnly();
// conControl.setReturnValue(false, 1);
// session2.setFlushMode(FlushMode.NEVER);
// session2Control.setVoidCallable(1);
//
// sf2Control.replay();
// session2Control.replay();
// txControl.replay();
// conControl.replay();
//
// MockServletContext sc = new MockServletContext();
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
// wac.setServletContext(sc);
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
// wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
// wac.refresh();
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
// filterConfig.addInitParameter("singleSession", "false");
// filterConfig2.addInitParameter("singleSession", "false");
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
//
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
// filter.init(filterConfig);
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
// filter2.init(filterConfig2);
//
// final FilterChain filterChain = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
// HibernateTransactionManager tm = new HibernateTransactionManager(sf);
// TransactionStatus ts = tm.getTransaction(
// new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
// SessionFactoryUtils.releaseSession(sess, sf);
// tm.commit(ts);
//
// sessionControl.verify();
// sessionControl.reset();
//
// session.close();
// sessionControl.setReturnValue(null, 1);
// sessionControl.replay();
//
// servletRequest.setAttribute("invoked", Boolean.TRUE);
// }
// };
//
// final FilterChain filterChain2 = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
// throws IOException, ServletException {
//
// HibernateTransactionManager tm = new HibernateTransactionManager(sf2);
// TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
// tm.commit(ts);
//
// session2Control.verify();
// session2Control.reset();
//
// session2.close();
// session2Control.setReturnValue(null, 1);
// session2Control.replay();
//
// filter.doFilter(servletRequest, servletResponse, filterChain);
// }
// };
//
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
//
// filter2.doFilter(request, response, filterChain3);
// assertNotNull(request.getAttribute("invoked"));
//
// sfControl.verify();
// sessionControl.verify();
// sf2Control.verify();
// session2Control.verify();
// txControl.verify();
// conControl.verify();
//
// wac.close();
// }
//
// public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception {
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
// final MockControl sessionControl = MockControl.createControl(Session.class);
// final Session session = (Session) sessionControl.getMock();
//
// sf.openSession();
// sfControl.setReturnValue(session, 1);
// session.getSessionFactory();
// sessionControl.setReturnValue(sf);
// session.getFlushMode();
// sessionControl.setReturnValue(FlushMode.NEVER, 1);
// session.setFlushMode(FlushMode.NEVER);
// sessionControl.setVoidCallable(1);
// sfControl.replay();
// sessionControl.replay();
//
// MockServletContext sc = new MockServletContext();
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
// wac.setServletContext(sc);
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
// wac.refresh();
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
// filterConfig.addInitParameter("singleSession", "false");
// filterConfig2.addInitParameter("singleSession", "false");
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
//
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
// rawInterceptor.setSessionFactory(sf);
// rawInterceptor.setSingleSession(false);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// interceptor.preHandle(request, response, "handler");
//
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
// filter.init(filterConfig);
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
// filter2.init(filterConfig2);
//
// final FilterChain filterChain = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
// HibernateTransactionManager tm = new HibernateTransactionManager(sf);
// TransactionStatus ts = tm.getTransaction(
// new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
// SessionFactoryUtils.releaseSession(sess, sf);
// tm.commit(ts);
//
// sessionControl.verify();
// sessionControl.reset();
// try {
// session.close();
// }
// catch (HibernateException ex) {
// }
// sessionControl.setReturnValue(null, 1);
// sessionControl.replay();
//
// servletRequest.setAttribute("invoked", Boolean.TRUE);
// }
// };
//
// FilterChain filterChain2 = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
// throws IOException, ServletException {
// filter.doFilter(servletRequest, servletResponse, filterChain);
// }
// };
//
// filter.doFilter(request, response, filterChain2);
// assertNotNull(request.getAttribute("invoked"));
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// sfControl.verify();
// sessionControl.verify();
//
// wac.close();
// }
}

View File

@ -0,0 +1,165 @@
/*
* Copyright 2002-2007 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.orm.jdo.support;
import org.junit.Ignore;
/**
* @author Juergen Hoeller
* @author Chris Beams
* @since 15.06.2004
*/
@Ignore // dependency issues after moving from .testsuite -> .test
public class OpenPersistenceManagerInViewTests {
// public void testOpenPersistenceManagerInViewInterceptor() throws Exception {
// MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
// PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
// MockControl pmControl = MockControl.createControl(PersistenceManager.class);
// PersistenceManager pm = (PersistenceManager) pmControl.getMock();
//
// OpenPersistenceManagerInViewInterceptor rawInterceptor = new OpenPersistenceManagerInViewInterceptor();
// rawInterceptor.setPersistenceManagerFactory(pmf);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// MockServletContext sc = new MockServletContext();
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// pmf.getPersistenceManager();
// pmfControl.setReturnValue(pm, 1);
// pmfControl.replay();
// pmControl.replay();
// interceptor.preHandle(request, response, "handler");
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
//
// // check that further invocations simply participate
// interceptor.preHandle(request, response, "handler");
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// pmfControl.verify();
// pmControl.verify();
//
// pmfControl.reset();
// pmControl.reset();
// pmfControl.replay();
// pmControl.replay();
// interceptor.postHandle(request, response, "handler", null);
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
// pmfControl.verify();
// pmControl.verify();
//
// pmfControl.reset();
// pmControl.reset();
// pm.close();
// pmControl.setVoidCallable(1);
// pmfControl.replay();
// pmControl.replay();
// interceptor.afterCompletion(request, response, "handler", null);
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
// pmfControl.verify();
// pmControl.verify();
// }
//
// public void testOpenPersistenceManagerInViewFilter() throws Exception {
// MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
// final PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
// MockControl pmControl = MockControl.createControl(PersistenceManager.class);
// PersistenceManager pm = (PersistenceManager) pmControl.getMock();
//
// pmf.getPersistenceManager();
// pmfControl.setReturnValue(pm, 1);
// pm.close();
// pmControl.setVoidCallable(1);
// pmfControl.replay();
// pmControl.replay();
//
// MockControl pmf2Control = MockControl.createControl(PersistenceManagerFactory.class);
// final PersistenceManagerFactory pmf2 = (PersistenceManagerFactory) pmf2Control.getMock();
// MockControl pm2Control = MockControl.createControl(PersistenceManager.class);
// PersistenceManager pm2 = (PersistenceManager) pm2Control.getMock();
//
// pmf2.getPersistenceManager();
// pmf2Control.setReturnValue(pm2, 1);
// pm2.close();
// pm2Control.setVoidCallable(1);
// pmf2Control.replay();
// pm2Control.replay();
//
// MockServletContext sc = new MockServletContext();
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
// wac.setServletContext(sc);
// wac.getDefaultListableBeanFactory().registerSingleton("persistenceManagerFactory", pmf);
// wac.getDefaultListableBeanFactory().registerSingleton("myPersistenceManagerFactory", pmf2);
// wac.refresh();
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
// filterConfig2.addInitParameter("persistenceManagerFactoryBeanName", "myPersistenceManagerFactory");
//
// final OpenPersistenceManagerInViewFilter filter = new OpenPersistenceManagerInViewFilter();
// filter.init(filterConfig);
// final OpenPersistenceManagerInViewFilter filter2 = new OpenPersistenceManagerInViewFilter();
// filter2.init(filterConfig2);
//
// final FilterChain filterChain = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
// servletRequest.setAttribute("invoked", Boolean.TRUE);
// }
// };
//
// final FilterChain filterChain2 = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
// throws IOException, ServletException {
// assertTrue(TransactionSynchronizationManager.hasResource(pmf2));
// filter.doFilter(servletRequest, servletResponse, filterChain);
// }
// };
//
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
//
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
// assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
// filter2.doFilter(request, response, filterChain3);
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
// assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
// assertNotNull(request.getAttribute("invoked"));
//
// pmfControl.verify();
// pmControl.verify();
// pmf2Control.verify();
// pm2Control.verify();
//
// wac.close();
// }
}

View File

@ -0,0 +1,187 @@
/*
* Copyright 2002-2007 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.orm.jpa.support;
import org.junit.Ignore;
import org.junit.Test;
/**
* @author Costin Leau
* @author Juergen Hoeller
* @author Chris Beams
*/
@Ignore // dependency issues after moving from .testsuite -> .test
public class OpenEntityManagerInViewTests {
// private MockControl factoryControl, managerControl;
//
// private EntityManager manager;
//
// private EntityManagerFactory factory;
//
// private JpaTemplate template;
//
//
// @Override
// protected void setUp() throws Exception {
// factoryControl = MockControl.createControl(EntityManagerFactory.class);
// factory = (EntityManagerFactory) factoryControl.getMock();
// managerControl = MockControl.createControl(EntityManager.class);
// manager = (EntityManager) managerControl.getMock();
//
// template = new JpaTemplate(factory);
// template.afterPropertiesSet();
//
// factoryControl.expectAndReturn(factory.createEntityManager(), manager);
// }
//
// @Override
// protected void tearDown() throws Exception {
// assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
// assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
// assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
// assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
// }
//
// public void testOpenEntityManagerInterceptorInView() throws Exception {
// OpenEntityManagerInViewInterceptor rawInterceptor = new OpenEntityManagerInViewInterceptor();
// rawInterceptor.setEntityManagerFactory(factory);
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
//
// MockServletContext sc = new MockServletContext();
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// managerControl.replay();
// factoryControl.replay();
//
// interceptor.preHandle(request, response, "handler");
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
//
// // check that further invocations simply participate
// interceptor.preHandle(request, response, "handler");
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// interceptor.preHandle(request, response, "handler");
// interceptor.postHandle(request, response, "handler", null);
// interceptor.afterCompletion(request, response, "handler", null);
//
// factoryControl.verify();
// managerControl.verify();
//
// managerControl.reset();
// factoryControl.reset();
// managerControl.replay();
// factoryControl.replay();
//
// interceptor.postHandle(request, response, "handler", null);
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
//
// factoryControl.verify();
// managerControl.verify();
//
// managerControl.reset();
// factoryControl.reset();
//
// manager.close();
//
// managerControl.replay();
// factoryControl.replay();
//
// interceptor.afterCompletion(request, response, "handler", null);
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
//
// factoryControl.verify();
// managerControl.verify();
// }
//
// public void testOpenEntityManagerInViewFilter() throws Exception {
// manager.close();
//
// managerControl.replay();
// factoryControl.replay();
//
// MockControl factoryControl2 = MockControl.createControl(EntityManagerFactory.class);
// final EntityManagerFactory factory2 = (EntityManagerFactory) factoryControl2.getMock();
//
// MockControl managerControl2 = MockControl.createControl(EntityManager.class);
// EntityManager manager2 = (EntityManager) managerControl2.getMock();
//
// factoryControl2.expectAndReturn(factory2.createEntityManager(), manager2);
// manager2.close();
//
// factoryControl2.replay();
// managerControl2.replay();
//
// MockServletContext sc = new MockServletContext();
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
// wac.setServletContext(sc);
// wac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", factory);
// wac.getDefaultListableBeanFactory().registerSingleton("myEntityManagerFactory", factory2);
// wac.refresh();
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
// MockHttpServletResponse response = new MockHttpServletResponse();
//
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
// filterConfig2.addInitParameter("entityManagerFactoryBeanName", "myEntityManagerFactory");
//
// final OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();
// filter.init(filterConfig);
// final OpenEntityManagerInViewFilter filter2 = new OpenEntityManagerInViewFilter();
// filter2.init(filterConfig2);
//
// final FilterChain filterChain = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
// servletRequest.setAttribute("invoked", Boolean.TRUE);
// }
// };
//
// final FilterChain filterChain2 = new FilterChain() {
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
// throws IOException, ServletException {
// assertTrue(TransactionSynchronizationManager.hasResource(factory2));
// filter.doFilter(servletRequest, servletResponse, filterChain);
// }
// };
//
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
//
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
// assertFalse(TransactionSynchronizationManager.hasResource(factory2));
// filter2.doFilter(request, response, filterChain3);
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
// assertFalse(TransactionSynchronizationManager.hasResource(factory2));
// assertNotNull(request.getAttribute("invoked"));
//
// factoryControl.verify();
// managerControl.verify();
// factoryControl2.verify();
// managerControl2.verify();
//
// wac.close();
// }
}

View File

@ -0,0 +1,292 @@
/*
* Copyright 2002-2008 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.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;
/**
* <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</code> property to <code>true</code> in
* the constructor to switch on Field Injection.
* </ul>
*
* @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})
*/
@Deprecated
public abstract class AbstractDependencyInjectionSpringContextTests extends AbstractSingleSpringContextTests {
/**
* Constant that indicates no autowiring at all.
*
* @see #setAutowireMode
*/
public static final int AUTOWIRE_NO = 0;
/**
* Constant that indicates autowiring bean properties by name.
*
* @see #setAutowireMode
*/
public 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;
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</code>.
*/
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.
* <p>The default is {@link #AUTOWIRE_BY_TYPE}. Can be set to
* {@link #AUTOWIRE_BY_NAME} or {@link #AUTOWIRE_NO} instead.
* @see #AUTOWIRE_BY_TYPE
* @see #AUTOWIRE_BY_NAME
* @see #AUTOWIRE_NO
*/
public final void setAutowireMode(final int autowireMode) {
this.autowireMode = autowireMode;
}
/**
* Return the autowire mode for test properties set by Dependency Injection.
*/
public final int getAutowireMode() {
return this.autowireMode;
}
/**
* Set whether or not dependency checking should be performed for test
* properties set by Dependency Injection.
* <p>The default is <code>true</code>, meaning that tests cannot be run
* unless all properties are populated.
*/
public final void setDependencyCheck(final boolean dependencyCheck) {
this.dependencyCheck = dependencyCheck;
}
/**
* Return whether or not dependency checking should be performed for test
* properties set by Dependency Injection.
*/
public final boolean isDependencyCheck() {
return this.dependencyCheck;
}
/**
* Prepare this test instance, injecting dependencies into its protected
* fields and its bean properties.
* <p>Note: if the {@link ApplicationContext} for this test instance has not
* been configured (e.g., is <code>null</code>), dependency injection
* will naturally <strong>not</strong> be performed, but an informational
* message will be written to the log.
* @see #injectDependencies()
*/
protected void prepareTestInstance() throws Exception {
if (getApplicationContext() == null) {
if (this.logger.isInfoEnabled()) {
this.logger.info("ApplicationContext has not been configured for test [" + getClass().getName()
+ "]: dependency injection will NOT be performed.");
}
}
else {
injectDependencies();
}
}
/**
* 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 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 = (String[]) 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;
}
}
}
}

View File

@ -0,0 +1,362 @@
/*
* Copyright 2002-2008 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 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.support.GenericApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
/**
* <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
* 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()}
* 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
* 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})
*/
@Deprecated
public abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTests {
/** 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</code> for custom behavior.
* @see #onSetUp()
*/
protected final void setUp() throws Exception {
// lazy load, in case getApplicationContext() has not yet been called.
if (this.applicationContext == null) {
this.applicationContext = getContext(contextKey());
}
prepareTestInstance();
onSetUp();
}
/**
* Prepare this test instance, for example populating its fields.
* The context has already been loaded at the time of this callback.
* <p>The default implementation does nothing.
* @throws Exception in case of preparation failure
*/
protected void prepareTestInstance() throws Exception {
}
/**
* Subclasses can override this method in place of the <code>setUp()</code>
* method, which is final in this class.
* <p>The default implementation does nothing.
* @throws Exception simply let any exception propagate
*/
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</code> for
* custom behavior.
* @see #onTearDown()
*/
protected final void tearDown() throws Exception {
onTearDown();
}
/**
* Subclasses can override this to add custom behavior on teardown.
* @throws Exception simply let any exception propagate
*/
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()</code> returns.
* @see #getConfigLocations()
*/
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
* {@link #createApplicationContext GenericApplicationContext}, allowing
* for customizing the internal bean factory through
* {@link #customizeBeanFactory}.
* @param locations the config locations (as Spring resource locations,
* e.g. full classpath locations or any kind of URL)
* @return the corresponding ApplicationContext instance (potentially cached)
* @throws Exception if context loading failed
* @see #createApplicationContext(String[])
*/
protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception {
++this.loadCount;
if (this.logger.isInfoEnabled()) {
this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations));
}
return createApplicationContext(locations);
}
/**
* Create a Spring {@link ConfigurableApplicationContext} for use by this test.
* <p>The default implementation creates a standard {@link GenericApplicationContext}
* instance, calls the {@link #prepareApplicationContext} prepareApplicationContext}
* method and the {@link #customizeBeanFactory customizeBeanFactory} method to allow
* for customizing the context and its DefaultListableBeanFactory, populates the
* context from the specified config <code>locations</code> through the configured
* {@link #createBeanDefinitionReader(GenericApplicationContext) BeanDefinitionReader},
* and finally {@link ConfigurableApplicationContext#refresh() refreshes} the context.
* @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 #customizeBeanFactory(DefaultListableBeanFactory)
* @see #createBeanDefinitionReader(GenericApplicationContext)
*/
protected ConfigurableApplicationContext createApplicationContext(String[] locations) {
GenericApplicationContext context = new GenericApplicationContext();
prepareApplicationContext(context);
customizeBeanFactory(context.getDefaultListableBeanFactory());
createBeanDefinitionReader(context).loadBeanDefinitions(locations);
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.
* <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
* config location path prefixed with "classpath:" with behave the same as a
* plain path, but a config location such as
* "file:/some/path/path/location/appContext.xml" will be treated as a
* filesystem location.
* <p>The default implementation builds config locations for the config paths
* specified through {@link #getConfigPaths()}.
* @return an array of config locations
* @see #getConfigPaths()
* @see org.springframework.core.io.ResourceLoader#getResource(String)
*/
protected String[] getConfigLocations() {
String[] paths = getConfigPaths();
String[] locations = 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;
}
else {
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX +
StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path);
}
}
return locations;
}
/**
* Subclasses can 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()}.
* @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</code>.
* @return an array of config locations
* @see #getConfigPath()
* @see java.lang.Class#getResource(String)
*/
protected String getConfigPath() {
return null;
}
/**
* Return the ApplicationContext that this base class manages; may be
* <code>null</code>.
*/
public final ConfigurableApplicationContext getApplicationContext() {
// lazy load, in case setUp() has not yet been called.
if (this.applicationContext == null) {
try {
this.applicationContext = getContext(contextKey());
}
catch (Exception e) {
// log and continue...
if (this.logger.isDebugEnabled()) {
this.logger.debug("Caught exception while retrieving the ApplicationContext for test [" +
getClass().getName() + "." + getName() + "].", e);
}
}
}
return this.applicationContext;
}
/**
* Return the current number of context load attempts.
*/
public final int getLoadCount() {
return this.loadCount;
}
}

View File

@ -0,0 +1,171 @@
/*
* Copyright 2002-2008 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.util.HashMap;
import java.util.Map;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* <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
* 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
* 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 AbstractSingleSpringContextTests
* @see AbstractDependencyInjectionSpringContextTests
* @see AbstractTransactionalSpringContextTests
* @see AbstractTransactionalDataSourceSpringContextTests
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
*/
@Deprecated
public abstract class AbstractSpringContextTests extends ConditionalTestCase {
/**
* 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>();
/**
* Default constructor for AbstractSpringContextTests.
*/
public AbstractSpringContextTests() {
}
/**
* Constructor for AbstractSpringContextTests with a JUnit name.
*/
public AbstractSpringContextTests(String name) {
super(name);
}
/**
* 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 context the ApplicationContext instance
*/
public final void addContext(Object key, 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</code> is <em>empty</em>.
* <p>By default, <code>null</code> values, empty strings, and zero-length
* arrays are considered <em>empty</em>.
* @param key the context key to check
* @return <code>true</code> 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));
}
/**
* Obtain an ApplicationContext for the given key, potentially cached.
* @param key the context key; may be <code>null</code>.
* @return the corresponding ApplicationContext instance (potentially cached),
* or <code>null</code> if the provided <code>key</code> is <em>empty</em>
*/
protected final ConfigurableApplicationContext getContext(Object key) throws Exception {
if (isContextKeyEmpty(key)) {
return null;
}
String keyString = contextKeyString(key);
ConfigurableApplicationContext ctx = contextKeyToContextMap.get(keyString);
if (ctx == null) {
ctx = loadContext(key);
ctx.registerShutdownHook();
contextKeyToContextMap.put(keyString, 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);
}
/**
* Load a new ApplicationContext for the given key.
* <p>To be implemented by subclasses.
* @param key the context key
* @return the corresponding ApplicationContext instance (new)
*/
protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception;
}

View File

@ -0,0 +1,199 @@
/*
* Copyright 2002-2008 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.io.IOException;
import java.io.LineNumberReader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.jdbc.JdbcTestUtils;
import org.springframework.util.StringUtils;
/**
* 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
public 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()</code> impossible.
* @see #setComplete
*/
protected void deleteFromTables(String[] names) {
for (int i = 0; i < names.length; i++) {
int rowCount = this.jdbcTemplate.update("DELETE FROM " + names[i]);
if (logger.isInfoEnabled()) {
logger.info("Deleted " + rowCount + " rows from table " + names[i]);
}
}
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()
*/
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.queryForInt("SELECT COUNT(0) FROM " + tableName);
}
/**
* Execute the given SQL script. Will be rolled back by default,
* according to the fate of the current transaction.
* @param sqlResourcePath Spring resource path for the SQL script.
* Should normally be loaded by classpath.
* <p>Statements should be delimited with a semicolon. If statements are not delimited with
* a semicolon then there should be one statement per line. Statements are allowed to span
* lines only if they are delimited with a semicolon.
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
* @param continueOnError whether or not to continue without throwing
* an exception in the event of an error
* @throws DataAccessException if there is an error executing a statement
* and continueOnError was false
*/
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
if (logger.isInfoEnabled()) {
logger.info("Executing SQL script '" + sqlResourcePath + "'");
}
EncodedResource resource =
new EncodedResource(getApplicationContext().getResource(sqlResourcePath), this.sqlScriptEncoding);
long startTime = System.currentTimeMillis();
List statements = new LinkedList();
try {
LineNumberReader lnr = new LineNumberReader(resource.getReader());
String script = JdbcTestUtils.readScript(lnr);
char delimiter = ';';
if (!JdbcTestUtils.containsSqlScriptDelimiters(script, delimiter)) {
delimiter = '\n';
}
JdbcTestUtils.splitSqlScript(script, delimiter, statements);
for (Iterator itr = statements.iterator(); itr.hasNext(); ) {
String statement = (String) itr.next();
try {
int rowsAffected = this.jdbcTemplate.update(statement);
if (logger.isDebugEnabled()) {
logger.debug(rowsAffected + " rows affected by SQL: " + statement);
}
}
catch (DataAccessException ex) {
if (continueOnError) {
if (logger.isWarnEnabled()) {
logger.warn("SQL: " + statement + " failed", ex);
}
}
else {
throw ex;
}
}
}
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Done executing SQL scriptBuilder '" + sqlResourcePath + "' in " + elapsedTime + " ms");
}
catch (IOException ex) {
throw new DataAccessResourceFailureException("Failed to open SQL script '" + sqlResourcePath + "'", ex);
}
}
}

View File

@ -0,0 +1,359 @@
/*
* Copyright 2002-2008 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 org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* Convenient base class for JUnit 3.8 based tests that should occur in a
* transaction, but normally will roll the transaction back on the completion of
* each test.
*
* <p>This is useful in a range of circumstances, allowing the following benefits:
* <ul>
* <li>Ability to delete or insert any data in the database, without affecting
* other tests
* <li>Providing a transactional context for any code requiring a transaction
* <li>Ability to write anything to the database without any need to clean up.
* </ul>
*
* <p>This class is typically very fast, compared to traditional setup/teardown
* scripts.
*
* <p>If data should be left in the database, call the {@link #setComplete()}
* method in each test. The {@link #setDefaultRollback "defaultRollback"}
* property, which defaults to "true", determines whether transactions will
* complete by default.
*
* <p>It is even possible to end the transaction early; for example, to verify lazy
* loading behavior of an O/R mapping tool. (This is a valuable away to avoid
* unexpected errors when testing a web UI, for example.) Simply call the
* {@link #endTransaction()} method. Execution will then occur without a
* transactional context.
*
* <p>The {@link #startNewTransaction()} method may be called after a call to
* {@link #endTransaction()} if you wish to create a new transaction, quite
* independent of the old transaction. The new transaction's default fate will
* be to roll back, unless {@link #setComplete()} is called again during the
* scope of the new transaction. Any number of transactions may be created and
* ended in this way. The final transaction will automatically be rolled back
* when the test case is torn down.
*
* <p>Transactional behavior requires a single bean in the context implementing the
* {@link PlatformTransactionManager} interface. This will be set by the
* superclass's Dependency Injection mechanism. If using the superclass's Field
* Injection mechanism, the implementation should be named "transactionManager".
* This mechanism allows the use of the
* {@link AbstractDependencyInjectionSpringContextTests} superclass even when
* there is more than one transaction manager in the context.
*
* <p><b>This base class can also be used without transaction management, if no
* PlatformTransactionManager bean is found in the context provided.</b> Be
* careful about using this mode, as it allows the potential to permanently
* modify data. This mode is available only if dependency checking is turned off
* in the {@link AbstractDependencyInjectionSpringContextTests} superclass. The
* non-transactional capability is provided to enable use of the same subclass
* in different environments.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @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
public abstract class AbstractTransactionalSpringContextTests extends AbstractDependencyInjectionSpringContextTests {
/** The transaction manager to use */
protected PlatformTransactionManager transactionManager;
/** Should we roll back by default? */
private boolean defaultRollback = true;
/** Should we commit the current transaction? */
private boolean complete = false;
/** Number of transactions started */
private int transactionsStarted = 0;
/**
* Transaction definition used by this test class: by default, a plain
* DefaultTransactionDefinition. Subclasses can change this to cause
* different behavior.
*/
protected TransactionDefinition transactionDefinition= new DefaultTransactionDefinition();
/**
* TransactionStatus for this test. Typical subclasses won't need to use it.
*/
protected TransactionStatus transactionStatus;
/**
* Default constructor for AbstractTransactionalSpringContextTests.
*/
public AbstractTransactionalSpringContextTests() {
}
/**
* 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
* the superclass.
* <p>
* This mode works only if dependency checking is turned off in the
* {@link AbstractDependencyInjectionSpringContextTests} superclass.
*/
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
/**
* 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) {
this.defaultRollback = defaultRollback;
}
/**
* Get the <em>default rollback</em> flag for this test.
* @see #setDefaultRollback(boolean)
* @return The <em>default rollback</em> flag.
*/
protected boolean isDefaultRollback() {
return this.defaultRollback;
}
/**
* Determines whether or not to rollback transactions for the current test.
* <p>The default implementation delegates to {@link #isDefaultRollback()}.
* Subclasses can override as necessary.
*/
protected boolean isRollback() {
return isDefaultRollback();
}
/**
* Call this method in an overridden {@link #runBare()} method to prevent
* transactional execution.
*/
protected void preventTransaction() {
this.transactionDefinition = null;
}
/**
* Call this method in an overridden {@link #runBare()} method to override
* the transaction attributes that will be used, so that {@link #setUp()}
* and {@link #tearDown()} behavior is modified.
* @param customDefinition the custom transaction definition
*/
protected void setTransactionDefinition(TransactionDefinition customDefinition) {
this.transactionDefinition = customDefinition;
}
/**
* This implementation creates a transaction before test execution.
* <p>Override {@link #onSetUpBeforeTransaction()} and/or
* {@link #onSetUpInTransaction()} to add custom set-up behavior for
* transactional execution. Alternatively, override this method for general
* set-up behavior, calling <code>super.onSetUp()</code> as part of your
* method implementation.
* @throws Exception simply let any exception propagate
* @see #onTearDown()
*/
protected void onSetUp() throws Exception {
this.complete = !this.isRollback();
if (this.transactionManager == null) {
this.logger.info("No transaction manager set: test will NOT run within a transaction");
}
else if (this.transactionDefinition == null) {
this.logger.info("No transaction definition set: test will NOT run within a transaction");
}
else {
onSetUpBeforeTransaction();
startNewTransaction();
try {
onSetUpInTransaction();
}
catch (final Exception ex) {
endTransaction();
throw ex;
}
}
}
/**
* Subclasses can override this method to perform any setup operations, such
* as populating a database table, <i>before</i> the transaction created by
* this class. Only invoked if there <i>is</i> a transaction: that is, if
* {@link #preventTransaction()} has not been invoked in an overridden
* {@link #runTest()} method.
* @throws Exception simply let any exception propagate
*/
protected void onSetUpBeforeTransaction() throws Exception {
}
/**
* Subclasses can override this method to perform any setup operations, such
* as populating a database table, <i>within</i> the transaction created by
* this class.
* <p><b>NB:</b> Not called if there is no transaction management, due to no
* transaction manager being provided in the context.
* <p>If any {@link Throwable} is thrown, the transaction that has been started
* prior to the execution of this method will be
* {@link #endTransaction() ended} (or rather an attempt will be made to
* {@link #endTransaction() end it gracefully}); The offending
* {@link Throwable} will then be rethrown.
* @throws Exception simply let any exception propagate
*/
protected void onSetUpInTransaction() throws Exception {
}
/**
* This implementation ends the transaction after test execution.
* <p>Override {@link #onTearDownInTransaction()} and/or
* {@link #onTearDownAfterTransaction()} to add custom tear-down behavior
* for transactional execution. Alternatively, override this method for
* general tear-down behavior, calling <code>super.onTearDown()</code> as
* part of your method implementation.
* <p>Note that {@link #onTearDownInTransaction()} will only be called if a
* transaction is still active at the time of the test shutdown. In
* particular, it will <i>not</i> be called if the transaction has been
* completed with an explicit {@link #endTransaction()} call before.
* @throws Exception simply let any exception propagate
* @see #onSetUp()
*/
protected void onTearDown() throws Exception {
// Call onTearDownInTransaction and end transaction if the transaction
// is still active.
if (this.transactionStatus != null && !this.transactionStatus.isCompleted()) {
try {
onTearDownInTransaction();
}
finally {
endTransaction();
}
}
// Call onTearDownAfterTransaction if there was at least one
// transaction, even if it has been completed early through an
// endTransaction() call.
if (this.transactionsStarted > 0) {
onTearDownAfterTransaction();
}
}
/**
* Subclasses can override this method to run invariant tests here. The
* transaction is <i>still active</i> at this point, so any changes made in
* the transaction will still be visible. However, there is no need to clean
* up the database, as a rollback will follow automatically.
* <p><b>NB:</b> Not called if there is no actual transaction, for example due
* to no transaction manager being provided in the application context.
* @throws Exception simply let any exception propagate
*/
protected void onTearDownInTransaction() throws Exception {
}
/**
* Subclasses can override this method to perform cleanup after a
* transaction here. At this point, the transaction is <i>not active anymore</i>.
* @throws Exception simply let any exception propagate
*/
protected void onTearDownAfterTransaction() throws Exception {
}
/**
* Cause the transaction to commit for this test method, even if the test
* method is configured to {@link #isRollback() rollback}.
* @throws IllegalStateException if the operation cannot be set to complete
* as no transaction manager was provided
*/
protected void setComplete() {
if (this.transactionManager == null) {
throw new IllegalStateException("No transaction manager set");
}
this.complete = true;
}
/**
* Immediately force a commit or rollback of the transaction, according to
* the <code>complete</code> and {@link #isRollback() rollback} flags.
* <p>Can be used to explicitly let the transaction end early, for example to
* check whether lazy associations of persistent objects work outside of a
* transaction (that is, have been initialized properly).
* @see #setComplete()
*/
protected void endTransaction() {
final boolean commit = this.complete || !isRollback();
if (this.transactionStatus != null) {
try {
if (commit) {
this.transactionManager.commit(this.transactionStatus);
this.logger.debug("Committed transaction after execution of test [" + getName() + "].");
}
else {
this.transactionManager.rollback(this.transactionStatus);
this.logger.debug("Rolled back transaction after execution of test [" + getName() + "].");
}
}
finally {
this.transactionStatus = null;
}
}
}
/**
* Start a new transaction. Only call this method if
* {@link #endTransaction()} has been called. {@link #setComplete()} can be
* used again in the new transaction. The fate of the new transaction, by
* default, will be the usual rollback.
* @throws TransactionException if starting the transaction failed
*/
protected void startNewTransaction() throws TransactionException {
if (this.transactionStatus != null) {
throw new IllegalStateException("Cannot start new transaction without ending existing transaction: "
+ "Invoke endTransaction() before startNewTransaction()");
}
if (this.transactionManager == null) {
throw new IllegalStateException("No transaction manager set");
}
this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition);
++this.transactionsStarted;
this.complete = !this.isRollback();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Began transaction (" + this.transactionsStarted + "): transaction manager ["
+ this.transactionManager + "]; rollback [" + this.isRollback() + "].");
}
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright 2002-2007 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 junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Superclass for JUnit 3.8 based tests that allows conditional test execution
* at the individual test method level. The
* {@link #isDisabledInThisEnvironment(String) isDisabledInThisEnvironment()}
* method is invoked before the execution of each test method. Subclasses can
* override that method to return whether or not the given test should be
* executed. Note that the tests will still appear to have executed and passed;
* however, log output will show that the test was not executed.
*
* @author Rod Johnson
* @since 2.0
* @see #isDisabledInThisEnvironment
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
*/
@Deprecated
public abstract class ConditionalTestCase extends TestCase {
private static int disabledTestCount;
/**
* 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());
/**
* Default constructor for ConditionalTestCase.
*/
public ConditionalTestCase() {
}
/**
* Constructor for ConditionalTestCase with a JUnit name.
*/
public ConditionalTestCase(String name) {
super(name);
}
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() + " 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;
}
}

View File

@ -0,0 +1,309 @@
/*
* Copyright 2002-2008 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.annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;
import javax.sql.DataSource;
import junit.framework.AssertionFailedError;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.util.Assert;
/**
* <p>
* Java 5 specific subclass of
* {@link AbstractTransactionalDataSourceSpringContextTests}, exposing a
* {@link SimpleJdbcTemplate} and obeying annotations for transaction control.
* </p>
* <p>
* For example, test methods can be annotated with the regular Spring
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
* annotation (e.g., to force execution in a read-only transaction) or with the
* {@link NotTransactional @NotTransactional} annotation to prevent any
* transaction being created at all. In addition, individual test methods can be
* annotated with {@link Rollback @Rollback} to override the
* {@link #isDefaultRollback() default rollback} settings.
* </p>
* <p>
* The following list constitutes all annotations currently supported by
* AbstractAnnotationAwareTransactionalTests:
* </p>
* <ul>
* <li>{@link DirtiesContext @DirtiesContext}</li>
* <li>{@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}</li>
* <li>{@link IfProfileValue @IfProfileValue}</li>
* <li>{@link ExpectedException @ExpectedException}</li>
* <li>{@link Timed @Timed}</li>
* <li>{@link Repeat @Repeat}</li>
* <li>{@link org.springframework.transaction.annotation.Transactional @Transactional}</li>
* <li>{@link NotTransactional @NotTransactional}</li>
* <li>{@link Rollback @Rollback}</li>
* </ul>
*
* @author Rod Johnson
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.0
*/
public abstract class AbstractAnnotationAwareTransactionalTests extends
AbstractTransactionalDataSourceSpringContextTests {
protected SimpleJdbcTemplate simpleJdbcTemplate;
private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
/**
* {@link ProfileValueSource} available to subclasses but primarily intended
* for use in {@link #isDisabledInThisEnvironment(Method)}.
* <p>Set to {@link SystemProfileValueSource} by default for backwards
* compatibility; however, the value may be changed in the
* {@link #AbstractAnnotationAwareTransactionalTests(String)} constructor.
*/
protected ProfileValueSource profileValueSource = SystemProfileValueSource.getInstance();
/**
* 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</code> and retrieves the configured (or
* default) {@link ProfileValueSource}.
* @param name the name of the current test
* @see ProfileValueUtils#retrieveProfileValueSource(Class)
*/
public AbstractAnnotationAwareTransactionalTests(String name) {
super(name);
this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass());
}
@Override
public void setDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
// JdbcTemplate will be identically configured
this.simpleJdbcTemplate = new SimpleJdbcTemplate(this.jdbcTemplate);
}
/**
* Search for a unique {@link ProfileValueSource} in the supplied
* {@link ApplicationContext}. If found, the
* <code>profileValueSource</code> for this test will be set to the unique
* {@link ProfileValueSource}.
* @param applicationContext the ApplicationContext in which to search for
* the ProfileValueSource; may not be <code>null</code>
* @deprecated Use {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} instead.
*/
@Deprecated
protected void findUniqueProfileValueSourceFromContext(ApplicationContext applicationContext) {
Assert.notNull(applicationContext, "Can not search for a ProfileValueSource in a null ApplicationContext.");
ProfileValueSource uniqueProfileValueSource = null;
Map<?, ?> beans = applicationContext.getBeansOfType(ProfileValueSource.class);
if (beans.size() == 1) {
uniqueProfileValueSource = (ProfileValueSource) beans.values().iterator().next();
}
if (uniqueProfileValueSource != null) {
this.profileValueSource = uniqueProfileValueSource;
}
}
/**
* 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();
if (isDisabledInThisEnvironment(testMethod)) {
recordDisabled();
this.logger.info("**** " + getClass().getName() + "." + getName() + " disabled in this environment: "
+ "Total disabled tests=" + getDisabledTestCount());
return;
}
TransactionDefinition explicitTransactionDefinition =
this.transactionAttributeSource.getTransactionAttribute(testMethod, getClass());
if (explicitTransactionDefinition != null) {
this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method ["
+ getName() + "].");
setTransactionDefinition(explicitTransactionDefinition);
}
else if (testMethod.isAnnotationPresent(NotTransactional.class)) {
// Don't have any transaction...
preventTransaction();
}
// Let JUnit handle execution. We're just changing the state of the test class first.
runTestTimed(new TestExecutionCallback() {
public void run() throws Throwable {
try {
AbstractAnnotationAwareTransactionalTests.super.runBare();
}
finally {
// Mark the context to be blown away if the test was
// annotated to result in setDirty being invoked
// automatically.
if (testMethod.isAnnotationPresent(DirtiesContext.class)) {
AbstractAnnotationAwareTransactionalTests.this.setDirty();
}
}
}
}, testMethod);
}
/**
* Determine if the test for the supplied <code>testMethod</code> should
* run in the current environment.
* <p>The default implementation is based on
* {@link IfProfileValue @IfProfileValue} semantics.
* @param testMethod the test method
* @return <code>true</code> if the test is <em>disabled</em> in the current environment
* @see ProfileValueUtils#isTestEnabledInThisEnvironment
*/
protected boolean isDisabledInThisEnvironment(Method testMethod) {
return !ProfileValueUtils.isTestEnabledInThisEnvironment(this.profileValueSource, testMethod, getClass());
}
/**
* 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 rollback transactions for the current test
* by taking into consideration the
* {@link #isDefaultRollback() default rollback} flag and a possible
* method-level override via the {@link Rollback @Rollback} annotation.
* @return the <em>rollback</em> flag for the current test
*/
@Override
protected boolean isRollback() {
boolean rollback = isDefaultRollback();
Rollback rollbackAnnotation = getTestMethod().getAnnotation(Rollback.class);
if (rollbackAnnotation != null) {
boolean rollbackOverride = rollbackAnnotation.value();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Method-level @Rollback(" + rollbackOverride + ") overrides default rollback ["
+ rollback + "] for test [" + getName() + "].");
}
rollback = rollbackOverride;
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("No method-level @Rollback override: using default rollback [" + rollback
+ "] for test [" + getName() + "].");
}
}
return rollback;
}
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());
}
}
}
}
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 != null && this.logger.isInfoEnabled()) {
this.logger.info("Repetition " + (i + 1) + " of test " + testMethod.getName());
}
tec.run();
if (exceptionIsExpected) {
fail("Expected exception: " + expectedException.getName());
}
}
catch (Throwable t) {
if (!exceptionIsExpected) {
throw t;
}
if (!expectedException.isAssignableFrom(t.getClass())) {
// Wrap the unexpected throwable with an explicit message.
AssertionFailedError assertionError = new AssertionFailedError("Unexpected exception, expected<" +
expectedException.getName() + "> but was<" + t.getClass().getName() + ">");
assertionError.initCause(t);
throw assertionError;
}
}
}
}
private static interface TestExecutionCallback {
void run() throws Throwable;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2002-2007 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Test annotation to indicate that a test method <em>dirties</em> the context
* for the current test.
* </p>
* <p>
* Using this annotation in conjunction with
* {@link AbstractAnnotationAwareTransactionalTests} is less error-prone than
* calling
* {@link org.springframework.test.AbstractSingleSpringContextTests#setDirty() setDirty()}
* explicitly because the call to <code>setDirty()</code> is guaranteed to
* occur, even if the test failed. If only a particular code path in the test
* dirties the context, prefer calling <code>setDirty()</code> explicitly --
* and take care!
* </p>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see org.springframework.test.AbstractSingleSpringContextTests
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DirtiesContext {
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2002-2007 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate that a test method is required to throw the
* specified exception.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExpectedException {
Class<? extends Throwable> value();
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2002-2008 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Test annotation to indicate that a test is enabled for a specific testing
* profile or environment. If the configured {@link ProfileValueSource} returns
* a matching {@link #value() value} for the provided {@link #name() name}, the
* test will be enabled.
* </p>
* <p>
* Note: {@link IfProfileValue @IfProfileValue} can be applied at either the
* class or method level.
* </p>
* <p>
* Examples: when using {@link SystemProfileValueSource} as the
* {@link ProfileValueSource} implementation, you can configure a test method to
* run only on Java VMs from Sun Microsystems as follows:
* </p>
*
* <pre class="code">
* {@link IfProfileValue @IfProfileValue}(name=&quot;java.vendor&quot;, value=&quot;Sun Microsystems Inc.&quot;)
* testSomething() {
* // ...
* }
* </pre>
*
* <p>
* You can alternatively configure {@link IfProfileValue @IfProfileValue} with
* <em>OR</em> semantics for multiple {@link #values() values} as follows
* (assuming a {@link ProfileValueSource} has been appropriately configured for
* the &quot;test-groups&quot; name):
* </p>
*
* <pre class="code">
* {@link IfProfileValue @IfProfileValue}(name=&quot;test-groups&quot;, values={&quot;unit-tests&quot;, &quot;integration-tests&quot;})
* public void testWhichRunsForUnitOrIntegrationTestGroups() {
* // ...
* }
* </pre>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see ProfileValueSource
* @see ProfileValueSourceConfiguration
* @see ProfileValueUtils
* @see AbstractAnnotationAwareTransactionalTests
* @see org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface IfProfileValue {
/**
* The <code>name</code> of the <em>profile value</em> against which to test.
*/
String name();
/**
* A single, permissible <code>value</code> of the <em>profile value</em>
* for the given {@link #name() name}.
* <p>Note: Assigning values to both {@link #value()} and {@link #values()}
* will lead to a configuration conflict.
*/
String value() default "";
/**
* A list of all permissible <code>values</code> of the
* <em>profile value</em> for the given {@link #name() name}.
* <p>Note: Assigning values to both {@link #value()} and {@link #values()}
* will lead to a configuration conflict.
*/
String[] values() default {};
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2002-2007 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate that a method is not transactional.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NotTransactional {
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2002-2008 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.annotation;
/**
* <p>
* Strategy interface for retrieving <em>profile values</em> for a given
* testing environment.
* </p>
* <p>
* Concrete implementations must provide a <code>public</code> no-args
* constructor.
* </p>
* <p>
* Spring provides the following out-of-the-box implementations:
* </p>
* <ul>
* <li>{@link SystemProfileValueSource}</li>
* </ul>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see ProfileValueSourceConfiguration
* @see IfProfileValue
* @see ProfileValueUtils
*/
public interface ProfileValueSource {
/**
* Get the <em>profile value</em> indicated by the specified key.
* @param key the name of the <em>profile value</em>
* @return the String value of the <em>profile value</em>, or <code>null</code>
* if there is no <em>profile value</em> with that key
*/
String get(String key);
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2002-2007 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* ProfileValueSourceConfiguration is a class-level annotation which is used to
* specify what type of {@link ProfileValueSource} to use when retrieving
* <em>profile values</em> configured via the
* {@link IfProfileValue @IfProfileValue} annotation.
* </p>
*
* @author Sam Brannen
* @since 2.5
* @see ProfileValueSource
* @see IfProfileValue
* @see ProfileValueUtils
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
public @interface ProfileValueSourceConfiguration {
/**
* <p>
* The type of {@link ProfileValueSource} to use when retrieving
* <em>profile values</em>.
* </p>
*
* @see SystemProfileValueSource
*/
Class<? extends ProfileValueSource> value() default SystemProfileValueSource.class;
}

View File

@ -0,0 +1,213 @@
/*
* Copyright 2002-2008 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.annotation;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* General utility methods for working with <em>profile values</em>.
*
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
* @see ProfileValueSource
* @see ProfileValueSourceConfiguration
* @see IfProfileValue
*/
public abstract class ProfileValueUtils {
private static final Log logger = LogFactory.getLog(ProfileValueUtils.class);
/**
* Retrieves the {@link ProfileValueSource} type for the specified
* {@link Class test class} as configured via the
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}
* annotation and instantiates a new instance of that type.
* <p>
* If
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}
* is not present on the specified class or if a custom
* {@link ProfileValueSource} is not declared, the default
* {@link SystemProfileValueSource} will be returned instead.
*
* @param testClass The test class for which the ProfileValueSource should
* be retrieved
* @return the configured (or default) ProfileValueSource for the specified
* class
* @see SystemProfileValueSource
*/
@SuppressWarnings("unchecked")
public static ProfileValueSource retrieveProfileValueSource(Class<?> testClass) {
Assert.notNull(testClass, "testClass must not be null");
Class<ProfileValueSourceConfiguration> annotationType = ProfileValueSourceConfiguration.class;
ProfileValueSourceConfiguration config = testClass.getAnnotation(annotationType);
if (logger.isDebugEnabled()) {
logger.debug("Retrieved @ProfileValueSourceConfiguration [" + config + "] for test class ["
+ testClass.getName() + "]");
}
Class<? extends ProfileValueSource> profileValueSourceType;
if (config != null) {
profileValueSourceType = config.value();
}
else {
profileValueSourceType = (Class<? extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType);
}
if (logger.isDebugEnabled()) {
logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class ["
+ testClass.getName() + "]");
}
ProfileValueSource profileValueSource;
if (SystemProfileValueSource.class.equals(profileValueSourceType)) {
profileValueSource = SystemProfileValueSource.getInstance();
}
else {
try {
profileValueSource = profileValueSourceType.newInstance();
}
catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("Could not instantiate a ProfileValueSource of type [" + profileValueSourceType
+ "] for class [" + testClass.getName() + "]: using default.", e);
}
profileValueSource = SystemProfileValueSource.getInstance();
}
}
return profileValueSource;
}
/**
* Determine if the supplied <code>testClass</code> is <em>enabled</em>
* in the current environment, as specified by the
* {@link IfProfileValue @IfProfileValue} annotation at the class level.
* <p>
* Defaults to <code>true</code> if no
* {@link IfProfileValue @IfProfileValue} annotation is declared.
*
* @param testClass the test class
* @return <code>true</code> if the test is <em>enabled</em> in the
* current environment
*/
public static boolean isTestEnabledInThisEnvironment(Class<?> testClass) {
IfProfileValue ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
return true;
}
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass);
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
/**
* Determine if the supplied <code>testMethod</code> is <em>enabled</em>
* in the current environment, as specified by the
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared
* on the test method itself or at the class level.
* <p>
* Defaults to <code>true</code> if no
* {@link IfProfileValue @IfProfileValue} annotation is declared.
*
* @param testMethod the test method
* @param testClass the test class
* @return <code>true</code> if the test is <em>enabled</em> in the
* current environment
*/
public static boolean isTestEnabledInThisEnvironment(Method testMethod, Class<?> testClass) {
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
return true;
}
}
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass);
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
/**
* Determine if the supplied <code>testMethod</code> is <em>enabled</em>
* in the current environment, as specified by the
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared
* on the test method itself or at the class level.
* <p>
* Defaults to <code>true</code> if no
* {@link IfProfileValue @IfProfileValue} annotation is declared.
*
* @param profileValueSource the ProfileValueSource to use to determine if
* the test is enabled
* @param testMethod the test method
* @param testClass the test class
* @return <code>true</code> if the test is <em>enabled</em> in the
* current environment
*/
public static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource, Method testMethod,
Class<?> testClass) {
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
if (ifProfileValue == null) {
return true;
}
}
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
}
/**
* Determine if the <code>value</code> (or one of the <code>values</code>)
* in the supplied {@link IfProfileValue @IfProfileValue} annotation is
* <em>enabled</em> in the current environment.
*
* @param profileValueSource the ProfileValueSource to use to determine if
* the test is enabled
* @param ifProfileValue the annotation to introspect
* @return <code>true</code> if the test is <em>enabled</em> in the
* current environment
*/
private static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource,
IfProfileValue ifProfileValue) {
String environmentValue = profileValueSource.get(ifProfileValue.name());
String[] annotatedValues = ifProfileValue.values();
if (StringUtils.hasLength(ifProfileValue.value())) {
if (annotatedValues.length > 0) {
throw new IllegalArgumentException("Setting both the 'value' and 'values' attributes "
+ "of @IfProfileValue is not allowed: choose one or the other.");
}
annotatedValues = new String[] { ifProfileValue.value() };
}
for (String value : annotatedValues) {
if (ObjectUtils.nullSafeEquals(value, environmentValue)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2002-2008 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate that a test method should be invoked repeatedly.
* <p />
* Note that the scope of execution to be repeated includes execution of the
* test method itself as well as any <em>set up</em> or <em>tear down</em>
* of the test fixture.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Repeat {
int value() default 1;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2002-2007 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Test annotation to indicate whether or not the transaction for the annotated
* test method should be <em>rolled back</em> after the test method has
* completed. If <code>true</code>, the transaction will be rolled back;
* otherwise, the transaction will be committed.
*
* @author Sam Brannen
* @since 2.5
*/
@Target( { ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Rollback {
/**
* <p>
* Whether or not the transaction for the annotated method should be rolled
* back after the method has completed.
* </p>
*/
boolean value() default true;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 2002-2007 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.annotation;
import org.springframework.util.Assert;
/**
* Implementation of {@link ProfileValueSource} which uses system properties as
* the underlying source.
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
*/
public class SystemProfileValueSource implements ProfileValueSource {
private static final SystemProfileValueSource INSTANCE = new SystemProfileValueSource();
/**
* Obtain the canonical instance of this ProfileValueSource.
*/
public static final SystemProfileValueSource getInstance() {
return INSTANCE;
}
/**
* Private constructor, enforcing the singleton pattern.
*/
private SystemProfileValueSource() {
}
/**
* Get the <em>profile value</em> indicated by the specified key from the
* system properties.
* @see System#getProperty(String)
*/
public String get(String key) {
Assert.hasText(key, "'key' must not be empty");
return System.getProperty(key);
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2002-2008 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Test-specific annotation to indicate that a test method has to finish
* execution in a {@link #millis() specified time period}.
* </p>
* <p>
* If the text execution takes longer than the specified time period, then the
* test is to be considered failed.
* </p>
* <p>
* Note that the time period includes execution of the test method itself, any
* {@link Repeat repetitions} of the test, and any <em>set up</em> or
* <em>tear down</em> of the test fixture.
* </p>
*
* @author Rod Johnson
* @author Sam Brannen
* @since 2.0
* @see Repeat
* @see AbstractAnnotationAwareTransactionalTests
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Timed {
/**
* The maximum amount of time (in milliseconds) that a test execution can
* take without being marked as failed due to taking too long.
*/
long millis();
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2002-2008 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.jdbc;
import org.springframework.util.StringUtils;
import java.util.List;
import java.io.LineNumberReader;
import java.io.IOException;
/**
* JdbcTestUtils is a collection of JDBC related utility methods for
* use in unit and integration testing scenarios.
*
* @author Thomas Risberg
* @since 2.5.4
*/
public class JdbcTestUtils {
/**
* Read a script from the LineNumberReaded and build a String containing the lines.
* @param lineNumberReader the <code>LineNumberReader</> containing the script to be processed
* @return <code>String</code> containing the script lines
* @throws IOException
*/
public static String readScript(LineNumberReader lineNumberReader) throws IOException {
String currentStatement = lineNumberReader.readLine();
StringBuilder scriptBuilder = new StringBuilder();
while (currentStatement != null) {
if (StringUtils.hasText(currentStatement)) {
if (scriptBuilder.length() > 0) {
scriptBuilder.append('\n');
}
scriptBuilder.append(currentStatement);
}
currentStatement = lineNumberReader.readLine();
}
return scriptBuilder.toString();
}
/**
* Does the provided SQL script contain the specified delimiter?
* @param script the SQL script
* @param delim charecter delimiting each statement - typically a ';' character
*/
public static boolean containsSqlScriptDelimiters(String script, char delim) {
boolean inLiteral = false;
char[] content = script.toCharArray();
for (int i = 0; i < script.length(); i++) {
if (content[i] == '\'') {
inLiteral = !inLiteral;
}
if (content[i] == delim && !inLiteral) {
return true;
}
}
return false;
}
/**
* Split an SQL script into separate statements delimited with the provided delimiter character. Each
* individual statement will be added to the provided <code>List</code>.
* @param script the SQL script
* @param delim charecter delimiting each statement - typically a ';' character
* @param statements the List that will contain the individual statements
*/
public static void splitSqlScript(String script, char delim, List<String> statements) {
StringBuilder sb = new StringBuilder();
boolean inLiteral = false;
char[] content = script.toCharArray();
for (int i = 0; i < script.length(); i++) {
if (content[i] == '\'') {
inLiteral = !inLiteral;
}
if (content[i] == delim && !inLiteral) {
if (sb.length() > 0) {
statements.add(sb.toString());
sb = new StringBuilder();
}
}
else {
sb.append(content[i]);
}
}
if (sb.length() > 0) {
statements.add(sb.toString());
}
}
}

View File

@ -0,0 +1,363 @@
/*
* Copyright 2002-2008 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.jpa;
import java.lang.instrument.ClassFileTransformer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
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;
import junit.framework.TestCase;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader;
import org.springframework.instrument.classloading.ShadowingClassLoader;
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.annotation.AbstractAnnotationAwareTransactionalTests;
import org.springframework.util.StringUtils;
/**
* Convenient support class for JPA-related tests. Offers the same contract as
* AbstractTransactionalDataSourceSpringContextTests and equally good performance,
* even when performing the instrumentation required by the JPA specification.
*
* <p>Exposes an EntityManagerFactory and a shared EntityManager.
* Requires an EntityManagerFactory to be injected, plus the DataSource and
* JpaTransactionManager through the superclass.
*
* <p>When using Xerces, make sure a post 2.0.2 version is available on the classpath
* to avoid a critical
* <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16014"/>bug</a>
* that leads to StackOverflow. Maven users are likely to encounter this problem since
* 2.0.2 is used by default.
*
* <p>A workaround is to explicitly specify the Xerces version inside the Maven POM:
* <pre>
* &lt;dependency&gt;
* &lt;groupId&gt;xerces&lt;/groupId&gt;
* &lt;artifactId&gt;xercesImpl&lt;/artifactId&gt;
* &lt;version&gt;2.8.1&lt;/version&gt;
* &lt;/dependency&gt;
* </pre>
*
* @author Rod Johnson
* @author Rob Harrop
* @author Juergen Hoeller
* @since 2.0
*/
public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactionalTests {
private static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml";
/**
* Map from String defining unique combination of config locations, to ApplicationContext.
* Values are intentionally not strongly typed, to avoid potential class cast exceptions
* through use between different class loaders.
*/
private static Map<String, Object> contextCache = new HashMap<String, Object>();
private static Map<String, ClassLoader> classLoaderCache = new HashMap<String, ClassLoader>();
protected EntityManagerFactory entityManagerFactory;
/**
* If this instance is in a shadow loader, this variable
* will contain the parent instance of the subclass.
* The class will not be the same as the class of the
* shadow instance, as it was loaded by a different class loader,
* but it can be invoked reflectively. The shadowParent
* and the shadow loader can communicate reflectively
* but not through direct invocation.
*/
private Object shadowParent;
/**
* Subclasses can use this in test cases.
* It will participate in any current transaction.
*/
protected EntityManager sharedEntityManager;
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory);
}
/**
* Create an EntityManager that will always automatically enlist itself in current
* transactions, in contrast to an EntityManager returned by
* <code>EntityManagerFactory.createEntityManager()</code>
* (which requires an explicit <code>joinTransaction()</code> call).
*/
protected EntityManager createContainerManagedEntityManager() {
return ExtendedEntityManagerCreator.createContainerManagedEntityManager(this.entityManagerFactory);
}
/**
* Subclasses should override this method if they wish to disable shadow class loading.
* <p>The default implementation deactivates shadow class loading if Spring's
* InstrumentationSavingAgent has been configured on VM startup.
*/
protected boolean shouldUseShadowLoader() {
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);
}
}
}
@Override
public void runBare() throws Throwable {
if (!shouldUseShadowLoader()) {
super.runBare();
return;
}
String combinationOfContextLocationsForThisTestClass = cacheKeys();
ClassLoader classLoaderForThisTestClass = getClass().getClassLoader();
// save the TCCL
ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
if (this.shadowParent != null) {
Thread.currentThread().setContextClassLoader(classLoaderForThisTestClass);
super.runBare();
}
else {
ShadowingClassLoader shadowingClassLoader = (ShadowingClassLoader) classLoaderCache.get(combinationOfContextLocationsForThisTestClass);
if (shadowingClassLoader == null) {
shadowingClassLoader = (ShadowingClassLoader) createShadowingClassLoader(classLoaderForThisTestClass);
classLoaderCache.put(combinationOfContextLocationsForThisTestClass, shadowingClassLoader);
}
try {
Thread.currentThread().setContextClassLoader(shadowingClassLoader);
String[] configLocations = getConfigLocations();
// Do not strongly type, to avoid ClassCastException.
Object cachedContext = contextCache.get(combinationOfContextLocationsForThisTestClass);
if (cachedContext == null) {
// Create the LoadTimeWeaver.
Class shadowingLoadTimeWeaverClass = shadowingClassLoader.loadClass(ShadowingLoadTimeWeaver.class.getName());
Constructor constructor = shadowingLoadTimeWeaverClass.getConstructor(ClassLoader.class);
constructor.setAccessible(true);
Object ltw = constructor.newInstance(shadowingClassLoader);
// Create the BeanFactory.
Class beanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName());
Object beanFactory = BeanUtils.instantiateClass(beanFactoryClass);
// Create the BeanDefinitionReader.
Class beanDefinitionReaderClass = shadowingClassLoader.loadClass(XmlBeanDefinitionReader.class.getName());
Class beanDefinitionRegistryClass = shadowingClassLoader.loadClass(BeanDefinitionRegistry.class.getName());
Object reader = beanDefinitionReaderClass.getConstructor(beanDefinitionRegistryClass).newInstance(beanFactory);
// Load the bean definitions into the BeanFactory.
Method loadBeanDefinitions = beanDefinitionReaderClass.getMethod("loadBeanDefinitions", String[].class);
loadBeanDefinitions.invoke(reader, new Object[] {configLocations});
// Create LoadTimeWeaver-injecting BeanPostProcessor.
Class loadTimeWeaverInjectingBeanPostProcessorClass = shadowingClassLoader.loadClass(LoadTimeWeaverInjectingBeanPostProcessor.class.getName());
Class loadTimeWeaverClass = shadowingClassLoader.loadClass(LoadTimeWeaver.class.getName());
Constructor bppConstructor = loadTimeWeaverInjectingBeanPostProcessorClass.getConstructor(loadTimeWeaverClass);
bppConstructor.setAccessible(true);
Object beanPostProcessor = bppConstructor.newInstance(ltw);
// Add LoadTimeWeaver-injecting BeanPostProcessor.
Class beanPostProcessorClass = shadowingClassLoader.loadClass(BeanPostProcessor.class.getName());
Method addBeanPostProcessor = beanFactoryClass.getMethod("addBeanPostProcessor", beanPostProcessorClass);
addBeanPostProcessor.invoke(beanFactory, beanPostProcessor);
// Create the GenericApplicationContext.
Class genericApplicationContextClass = shadowingClassLoader.loadClass(GenericApplicationContext.class.getName());
Class defaultListableBeanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName());
cachedContext = genericApplicationContextClass.getConstructor(defaultListableBeanFactoryClass).newInstance(beanFactory);
// Invoke the context's "refresh" method.
genericApplicationContextClass.getMethod("refresh").invoke(cachedContext);
// Store the context reference in the cache.
contextCache.put(combinationOfContextLocationsForThisTestClass, cachedContext);
}
// create the shadowed test
Class shadowedTestClass = shadowingClassLoader.loadClass(getClass().getName());
// So long as JUnit is excluded from shadowing we
// can minimize reflective invocation here
TestCase shadowedTestCase = (TestCase) BeanUtils.instantiateClass(shadowedTestClass);
/* shadowParent = this */
Class thisShadowedClass = shadowingClassLoader.loadClass(AbstractJpaTests.class.getName());
Field shadowed = thisShadowedClass.getDeclaredField("shadowParent");
shadowed.setAccessible(true);
shadowed.set(shadowedTestCase, this);
/* AbstractSpringContextTests.addContext(Object, ApplicationContext) */
Class applicationContextClass = shadowingClassLoader.loadClass(ConfigurableApplicationContext.class.getName());
Method addContextMethod = shadowedTestClass.getMethod("addContext", Object.class, applicationContextClass);
addContextMethod.invoke(shadowedTestCase, configLocations, cachedContext);
// Invoke tests on shadowed test case
shadowedTestCase.setName(getName());
shadowedTestCase.runBare();
}
catch (InvocationTargetException ex) {
// Unwrap this for better exception reporting
// when running tests
throw ex.getTargetException();
}
finally {
Thread.currentThread().setContextClassLoader(initialClassLoader);
}
}
}
protected String cacheKeys() {
return StringUtils.arrayToCommaDelimitedString(getConfigLocations());
}
/**
* NB: This method must <b>not</b> have a return type of ShadowingClassLoader as that would cause that
* class to be loaded eagerly when this test case loads, creating verify errors at runtime.
*/
protected ClassLoader createShadowingClassLoader(ClassLoader classLoader) {
OrmXmlOverridingShadowingClassLoader orxl = new OrmXmlOverridingShadowingClassLoader(classLoader,
getActualOrmXmlLocation());
customizeResourceOverridingShadowingClassLoader(orxl);
return orxl;
}
/**
* Customize the shadowing class loader.
* @param shadowingClassLoader this parameter is actually of type
* ResourceOverridingShadowingClassLoader, and can safely to be cast to
* that type. However, the signature must not be of that type as that
* would cause the present class loader to load that type.
*/
protected void customizeResourceOverridingShadowingClassLoader(ClassLoader shadowingClassLoader) {
// empty
}
/**
* Subclasses can override this to return the real location path for
* orm.xml or null if they do not wish to find any orm.xml
* @return orm.xml path or null to hide any such file
*/
protected String getActualOrmXmlLocation() {
return DEFAULT_ORM_XML_LOCATION;
}
private static class LoadTimeWeaverInjectingBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
private final LoadTimeWeaver ltw;
public LoadTimeWeaverInjectingBeanPostProcessor(LoadTimeWeaver ltw) {
this.ltw = ltw;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LocalContainerEntityManagerFactoryBean) {
((LocalContainerEntityManagerFactoryBean) bean).setLoadTimeWeaver(this.ltw);
}
if (bean instanceof DefaultPersistenceUnitManager) {
((DefaultPersistenceUnitManager) bean).setLoadTimeWeaver(this.ltw);
}
return bean;
}
}
private static class ShadowingLoadTimeWeaver implements LoadTimeWeaver {
private final ClassLoader shadowingClassLoader;
public ShadowingLoadTimeWeaver(ClassLoader shadowingClassLoader) {
this.shadowingClassLoader = shadowingClassLoader;
}
public void addTransformer(ClassFileTransformer transformer) {
try {
Method addClassFileTransformer =
this.shadowingClassLoader.getClass().getMethod("addTransformer", ClassFileTransformer.class);
addClassFileTransformer.setAccessible(true);
addClassFileTransformer.invoke(this.shadowingClassLoader, transformer);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public ClassLoader getInstrumentableClassLoader() {
return this.shadowingClassLoader;
}
public ClassLoader getThrowawayClassLoader() {
// Be sure to copy the same resource overrides and same class file transformers:
// We want the throwaway class loader to behave like the instrumentable class loader.
ResourceOverridingShadowingClassLoader roscl =
new ResourceOverridingShadowingClassLoader(getClass().getClassLoader());
if (this.shadowingClassLoader instanceof ShadowingClassLoader) {
roscl.copyTransformers((ShadowingClassLoader) this.shadowingClassLoader);
}
if (this.shadowingClassLoader instanceof ResourceOverridingShadowingClassLoader) {
roscl.copyOverrides((ResourceOverridingShadowingClassLoader) this.shadowingClassLoader);
}
return roscl;
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright 2002-2007 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.jpa;
import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader;
/**
* Subclass of ShadowingClassLoader that overrides attempts to
* locate <code>orm.xml</code>.
*
* <p>This class must <b>not</b> be an inner class of AbstractJpaTests
* to avoid it being loaded until first used.
*
* @author Rod Johnson
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
class OrmXmlOverridingShadowingClassLoader extends ResourceOverridingShadowingClassLoader {
/**
* Default location of the <code>orm.xml</code> file in the class path:
* "META-INF/orm.xml"
*/
public static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml";
public OrmXmlOverridingShadowingClassLoader(ClassLoader loader, String realOrmXmlLocation) {
super(loader);
// Automatically exclude classes from these well-known persistence providers.
// Do NOT exclude Hibernate classes --
// this causes class casts due to use of CGLIB by Hibernate.
// Same goes for OpenJPA which will not enhance the domain classes.
excludePackage("oracle.toplink.essentials");
excludePackage("junit");
override(DEFAULT_ORM_XML_LOCATION, realOrmXmlLocation);
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 2002-2005 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.transaction;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.xa.XAResource;
/**
* @author Juergen Hoeller
* @since 31.08.2004
*/
public class MockJtaTransaction implements javax.transaction.Transaction {
private Synchronization synchronization;
public int getStatus() {
return Status.STATUS_ACTIVE;
}
public void registerSynchronization(Synchronization synchronization) {
this.synchronization = synchronization;
}
public Synchronization getSynchronization() {
return synchronization;
}
public boolean enlistResource(XAResource xaResource) {
return false;
}
public boolean delistResource(XAResource xaResource, int i) {
return false;
}
public void commit() {
}
public void rollback() {
}
public void setRollbackOnly() {
}
}

View File

@ -0,0 +1,97 @@
/*
* The Spring Framework is published under the terms
* of the Apache Software License.
*/
package org.springframework.util;
import java.awt.Point;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import junit.framework.TestCase;
import org.springframework.beans.TestBean;
/**
* Utilities for testing serializability of objects.
* Exposes static methods for use in other test cases.
* Extends TestCase only to test itself.
*
* @author Rod Johnson
*/
public class SerializationTestUtils extends TestCase {
public static void testSerialization(Object o) throws IOException {
OutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
}
public static boolean isSerializable(Object o) throws IOException {
try {
testSerialization(o);
return true;
}
catch (NotSerializableException ex) {
return false;
}
}
public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.flush();
baos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(is);
Object o2 = ois.readObject();
return o2;
}
public SerializationTestUtils(String s) {
super(s);
}
public void testWithNonSerializableObject() throws IOException {
TestBean o = new TestBean();
assertFalse(o instanceof Serializable);
assertFalse(isSerializable(o));
try {
testSerialization(o);
fail();
}
catch (NotSerializableException ex) {
// Ok
}
}
public void testWithSerializableObject() throws Exception {
int x = 5;
int y = 10;
Point p = new Point(x, y);
assertTrue(p instanceof Serializable);
testSerialization(p);
assertTrue(isSerializable(p));
Point p2 = (Point) serializeAndDeserialize(p);
assertNotSame(p, p2);
assertEquals(x, (int) p2.getX());
assertEquals(y, (int) p2.getY());
}
}

View File

@ -13,7 +13,6 @@
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.web"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.web.portlet"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.web.servlet"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.orm"/>
<classpathentry kind="var" path="IVY_CACHE/javax.activation/com.springsource.javax.activation/1.1.0/com.springsource.javax.activation-1.1.0.jar" sourcepath="/IVY_CACHE/javax.activation/com.springsource.javax.activation/1.1.0/com.springsource.javax.activation-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-1.0.0.jar" sourcepath="/IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.portlet/com.springsource.javax.portlet/1.0.0/com.springsource.javax.portlet-1.0.0.jar"/>
@ -26,5 +25,6 @@
<classpathentry kind="var" path="IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-1.1.2.jar" sourcepath="/IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-sources-1.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.2.RELEASE/com.springsource.org.aspectj.weaver-1.6.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.el/com.springsource.javax.el/2.1.0/com.springsource.javax.el-2.1.0.jar" sourcepath="/IVY_CACHE/javax.el/com.springsource.javax.el/2.1.0/com.springsource.javax.el-sources-2.1.0.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.orm"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -20,6 +20,7 @@ import static org.junit.Assert.*;
import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
/**
@ -29,6 +30,7 @@ import org.junit.Test;
*/
public class MockServletContextTests {
@Ignore // fails to work under ant after move from .testsuite -> .test
@Test
public void testListFiles() {
MockServletContext sc = new MockServletContext("org/springframework/mock");
@ -37,6 +39,7 @@ public class MockServletContextTests {
assertTrue(paths.contains("/web/MockServletContextTests.class"));
}
@Ignore // fails to work under ant after move from .testsuite -> .test
@Test
public void testListSubdirectories() {
MockServletContext sc = new MockServletContext("org/springframework/mock");

View File

@ -1,663 +0,0 @@
/*
* Copyright 2002-2007 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.orm.hibernate3.support;
import java.io.IOException;
import java.sql.Connection;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.transaction.TransactionManager;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.engine.SessionFactoryImplementor;
import org.junit.Ignore;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.PassThroughFilterChain;
import org.springframework.orm.hibernate3.HibernateAccessor;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
/**
* @author Juergen Hoeller
* @since 05.03.2005
*/
@Ignore // getting errors on mocks
public class OpenSessionInViewTests extends TestCase {
public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
Session session = (Session) sessionControl.getMock();
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
rawInterceptor.setSessionFactory(sf);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
MockServletContext sc = new MockServletContext();
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf, 2);
session.isOpen();
sessionControl.setReturnValue(true, 1);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
sfControl.replay();
sessionControl.replay();
interceptor.preHandle(request, response, "handler");
assertTrue(TransactionSynchronizationManager.hasResource(sf));
// check that further invocations simply participate
interceptor.preHandle(request, response, "handler");
assertEquals(session, SessionFactoryUtils.getSession(sf, false));
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
sfControl.replay();
sessionControl.replay();
interceptor.postHandle(request, response, "handler", null);
assertTrue(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
interceptor.afterCompletion(request, response, "handler", null);
assertFalse(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
}
public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactoryImplementor.class);
final SessionFactoryImplementor sf = (SessionFactoryImplementor) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
Session session = (Session) sessionControl.getMock();
MockControl tmControl = MockControl.createControl(TransactionManager.class);
TransactionManager tm = (TransactionManager) tmControl.getMock();
tm.getTransaction();
tmControl.setReturnValue(null, 2);
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
rawInterceptor.setSessionFactory(sf);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
MockServletContext sc = new MockServletContext();
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
sf.getTransactionManager();
sfControl.setReturnValue(tm, 2);
sf.openSession();
sfControl.setReturnValue(session, 1);
session.isOpen();
sessionControl.setReturnValue(true, 1);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
tmControl.replay();
sfControl.replay();
sessionControl.replay();
interceptor.preHandle(request, response, "handler");
assertTrue(TransactionSynchronizationManager.hasResource(sf));
// check that further invocations simply participate
interceptor.preHandle(request, response, "handler");
assertEquals(session, SessionFactoryUtils.getSession(sf, false));
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
sfControl.replay();
sessionControl.replay();
interceptor.postHandle(request, response, "handler", null);
assertTrue(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
interceptor.afterCompletion(request, response, "handler", null);
assertFalse(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
}
public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
Session session = (Session) sessionControl.getMock();
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
rawInterceptor.setSessionFactory(sf);
rawInterceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
MockServletContext sc = new MockServletContext();
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf);
sfControl.replay();
sessionControl.replay();
interceptor.preHandle(request, response, "handler");
assertTrue(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
session.flush();
sessionControl.setVoidCallable(1);
sfControl.replay();
sessionControl.replay();
interceptor.postHandle(request, response, "handler", null);
assertTrue(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
interceptor.afterCompletion(request, response, "handler", null);
assertFalse(TransactionSynchronizationManager.hasResource(sf));
sfControl.verify();
sessionControl.verify();
}
public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
Session session = (Session) sessionControl.getMock();
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
rawInterceptor.setSessionFactory(sf);
rawInterceptor.setSingleSession(false);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
MockServletContext sc = new MockServletContext();
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf, 1);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
sfControl.replay();
sessionControl.replay();
interceptor.preHandle(request, response, "handler");
org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
SessionFactoryUtils.releaseSession(sess, sf);
// check that further invocations simply participate
interceptor.preHandle(request, response, "handler");
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
sfControl.verify();
sessionControl.verify();
sfControl.reset();
sessionControl.reset();
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
sfControl.verify();
sessionControl.verify();
}
public void testOpenSessionInViewFilterWithSingleSession() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
Session session = (Session) sessionControl.getMock();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
MockControl sf2Control = MockControl.createControl(SessionFactory.class);
final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
MockControl session2Control = MockControl.createControl(Session.class);
Session session2 = (Session) session2Control.getMock();
sf2.openSession();
sf2Control.setReturnValue(session2, 1);
session2.getSessionFactory();
session2Control.setReturnValue(sf);
session2.setFlushMode(FlushMode.AUTO);
session2Control.setVoidCallable(1);
session2.close();
session2Control.setReturnValue(null, 1);
sf2Control.replay();
session2Control.replay();
MockServletContext sc = new MockServletContext();
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(sc);
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
wac.refresh();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
filterConfig2.addInitParameter("flushMode", "AUTO");
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
filter.init(filterConfig);
final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
filter2.init(filterConfig2);
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
assertTrue(TransactionSynchronizationManager.hasResource(sf));
servletRequest.setAttribute("invoked", Boolean.TRUE);
}
};
final FilterChain filterChain2 = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
throws IOException, ServletException {
assertTrue(TransactionSynchronizationManager.hasResource(sf2));
filter.doFilter(servletRequest, servletResponse, filterChain);
}
};
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
assertFalse(TransactionSynchronizationManager.hasResource(sf));
assertFalse(TransactionSynchronizationManager.hasResource(sf2));
filter2.doFilter(request, response, filterChain3);
assertFalse(TransactionSynchronizationManager.hasResource(sf));
assertFalse(TransactionSynchronizationManager.hasResource(sf2));
assertNotNull(request.getAttribute("invoked"));
sfControl.verify();
sessionControl.verify();
sf2Control.verify();
session2Control.verify();
wac.close();
}
public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
Session session = (Session) sessionControl.getMock();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
MockServletContext sc = new MockServletContext();
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(sc);
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
wac.refresh();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
rawInterceptor.setSessionFactory(sf);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
interceptor.preHandle(request, response, "handler");
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
filter.init(filterConfig);
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
assertTrue(TransactionSynchronizationManager.hasResource(sf));
servletRequest.setAttribute("invoked", Boolean.TRUE);
}
};
assertTrue(TransactionSynchronizationManager.hasResource(sf));
filter.doFilter(request, response, filterChain);
assertTrue(TransactionSynchronizationManager.hasResource(sf));
assertNotNull(request.getAttribute("invoked"));
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
sfControl.verify();
sessionControl.verify();
wac.close();
}
public void testOpenSessionInViewFilterWithDeferredClose() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
final MockControl sessionControl = MockControl.createControl(Session.class);
final Session session = (Session) sessionControl.getMock();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf);
session.getFlushMode();
sessionControl.setReturnValue(FlushMode.NEVER, 1);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
sfControl.replay();
sessionControl.replay();
MockControl sf2Control = MockControl.createControl(SessionFactory.class);
final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
final MockControl session2Control = MockControl.createControl(Session.class);
final Session session2 = (Session) session2Control.getMock();
MockControl txControl = MockControl.createControl(Transaction.class);
Transaction tx = (Transaction) txControl.getMock();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
sf2.openSession();
sf2Control.setReturnValue(session2, 1);
session2.beginTransaction();
session2Control.setReturnValue(tx, 1);
session2.connection();
session2Control.setReturnValue(con, 2);
tx.commit();
txControl.setVoidCallable(1);
session2.isConnected();
session2Control.setReturnValue(true, 1);
con.isReadOnly();
conControl.setReturnValue(false, 1);
session2.setFlushMode(FlushMode.NEVER);
session2Control.setVoidCallable(1);
sf2Control.replay();
session2Control.replay();
txControl.replay();
conControl.replay();
MockServletContext sc = new MockServletContext();
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(sc);
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
wac.refresh();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
filterConfig.addInitParameter("singleSession", "false");
filterConfig2.addInitParameter("singleSession", "false");
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
filter.init(filterConfig);
final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
filter2.init(filterConfig2);
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
HibernateTransactionManager tm = new HibernateTransactionManager(sf);
TransactionStatus ts = tm.getTransaction(
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
SessionFactoryUtils.releaseSession(sess, sf);
tm.commit(ts);
sessionControl.verify();
sessionControl.reset();
session.close();
sessionControl.setReturnValue(null, 1);
sessionControl.replay();
servletRequest.setAttribute("invoked", Boolean.TRUE);
}
};
final FilterChain filterChain2 = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
throws IOException, ServletException {
HibernateTransactionManager tm = new HibernateTransactionManager(sf2);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
tm.commit(ts);
session2Control.verify();
session2Control.reset();
session2.close();
session2Control.setReturnValue(null, 1);
session2Control.replay();
filter.doFilter(servletRequest, servletResponse, filterChain);
}
};
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
filter2.doFilter(request, response, filterChain3);
assertNotNull(request.getAttribute("invoked"));
sfControl.verify();
sessionControl.verify();
sf2Control.verify();
session2Control.verify();
txControl.verify();
conControl.verify();
wac.close();
}
public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
final MockControl sessionControl = MockControl.createControl(Session.class);
final Session session = (Session) sessionControl.getMock();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf);
session.getFlushMode();
sessionControl.setReturnValue(FlushMode.NEVER, 1);
session.setFlushMode(FlushMode.NEVER);
sessionControl.setVoidCallable(1);
sfControl.replay();
sessionControl.replay();
MockServletContext sc = new MockServletContext();
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(sc);
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
wac.refresh();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
filterConfig.addInitParameter("singleSession", "false");
filterConfig2.addInitParameter("singleSession", "false");
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
rawInterceptor.setSessionFactory(sf);
rawInterceptor.setSingleSession(false);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
interceptor.preHandle(request, response, "handler");
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
filter.init(filterConfig);
final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
filter2.init(filterConfig2);
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
HibernateTransactionManager tm = new HibernateTransactionManager(sf);
TransactionStatus ts = tm.getTransaction(
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
SessionFactoryUtils.releaseSession(sess, sf);
tm.commit(ts);
sessionControl.verify();
sessionControl.reset();
try {
session.close();
}
catch (HibernateException ex) {
}
sessionControl.setReturnValue(null, 1);
sessionControl.replay();
servletRequest.setAttribute("invoked", Boolean.TRUE);
}
};
FilterChain filterChain2 = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
throws IOException, ServletException {
filter.doFilter(servletRequest, servletResponse, filterChain);
}
};
filter.doFilter(request, response, filterChain2);
assertNotNull(request.getAttribute("invoked"));
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
sfControl.verify();
sessionControl.verify();
wac.close();
}
}

View File

@ -1,183 +0,0 @@
/*
* Copyright 2002-2007 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.orm.jdo.support;
import java.io.IOException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.PassThroughFilterChain;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
/**
* @author Juergen Hoeller
* @since 15.06.2004
*/
public class OpenPersistenceManagerInViewTests extends TestCase {
public void testOpenPersistenceManagerInViewInterceptor() throws Exception {
MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
MockControl pmControl = MockControl.createControl(PersistenceManager.class);
PersistenceManager pm = (PersistenceManager) pmControl.getMock();
OpenPersistenceManagerInViewInterceptor rawInterceptor = new OpenPersistenceManagerInViewInterceptor();
rawInterceptor.setPersistenceManagerFactory(pmf);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
MockServletContext sc = new MockServletContext();
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
pmf.getPersistenceManager();
pmfControl.setReturnValue(pm, 1);
pmfControl.replay();
pmControl.replay();
interceptor.preHandle(request, response, "handler");
assertTrue(TransactionSynchronizationManager.hasResource(pmf));
// check that further invocations simply participate
interceptor.preHandle(request, response, "handler");
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
pmfControl.verify();
pmControl.verify();
pmfControl.reset();
pmControl.reset();
pmfControl.replay();
pmControl.replay();
interceptor.postHandle(request, response, "handler", null);
assertTrue(TransactionSynchronizationManager.hasResource(pmf));
pmfControl.verify();
pmControl.verify();
pmfControl.reset();
pmControl.reset();
pm.close();
pmControl.setVoidCallable(1);
pmfControl.replay();
pmControl.replay();
interceptor.afterCompletion(request, response, "handler", null);
assertFalse(TransactionSynchronizationManager.hasResource(pmf));
pmfControl.verify();
pmControl.verify();
}
public void testOpenPersistenceManagerInViewFilter() throws Exception {
MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
final PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
MockControl pmControl = MockControl.createControl(PersistenceManager.class);
PersistenceManager pm = (PersistenceManager) pmControl.getMock();
pmf.getPersistenceManager();
pmfControl.setReturnValue(pm, 1);
pm.close();
pmControl.setVoidCallable(1);
pmfControl.replay();
pmControl.replay();
MockControl pmf2Control = MockControl.createControl(PersistenceManagerFactory.class);
final PersistenceManagerFactory pmf2 = (PersistenceManagerFactory) pmf2Control.getMock();
MockControl pm2Control = MockControl.createControl(PersistenceManager.class);
PersistenceManager pm2 = (PersistenceManager) pm2Control.getMock();
pmf2.getPersistenceManager();
pmf2Control.setReturnValue(pm2, 1);
pm2.close();
pm2Control.setVoidCallable(1);
pmf2Control.replay();
pm2Control.replay();
MockServletContext sc = new MockServletContext();
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(sc);
wac.getDefaultListableBeanFactory().registerSingleton("persistenceManagerFactory", pmf);
wac.getDefaultListableBeanFactory().registerSingleton("myPersistenceManagerFactory", pmf2);
wac.refresh();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
filterConfig2.addInitParameter("persistenceManagerFactoryBeanName", "myPersistenceManagerFactory");
final OpenPersistenceManagerInViewFilter filter = new OpenPersistenceManagerInViewFilter();
filter.init(filterConfig);
final OpenPersistenceManagerInViewFilter filter2 = new OpenPersistenceManagerInViewFilter();
filter2.init(filterConfig2);
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
assertTrue(TransactionSynchronizationManager.hasResource(pmf));
servletRequest.setAttribute("invoked", Boolean.TRUE);
}
};
final FilterChain filterChain2 = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
throws IOException, ServletException {
assertTrue(TransactionSynchronizationManager.hasResource(pmf2));
filter.doFilter(servletRequest, servletResponse, filterChain);
}
};
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
assertFalse(TransactionSynchronizationManager.hasResource(pmf));
assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
filter2.doFilter(request, response, filterChain3);
assertFalse(TransactionSynchronizationManager.hasResource(pmf));
assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
assertNotNull(request.getAttribute("invoked"));
pmfControl.verify();
pmControl.verify();
pmf2Control.verify();
pm2Control.verify();
wac.close();
}
}

View File

@ -1,206 +0,0 @@
/*
* Copyright 2002-2007 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.orm.jpa.support;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.PassThroughFilterChain;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
/**
* @author Costin Leau
* @author Juergen Hoeller
*/
public class OpenEntityManagerInViewTests extends TestCase {
private MockControl factoryControl, managerControl;
private EntityManager manager;
private EntityManagerFactory factory;
private JpaTemplate template;
@Override
protected void setUp() throws Exception {
factoryControl = MockControl.createControl(EntityManagerFactory.class);
factory = (EntityManagerFactory) factoryControl.getMock();
managerControl = MockControl.createControl(EntityManager.class);
manager = (EntityManager) managerControl.getMock();
template = new JpaTemplate(factory);
template.afterPropertiesSet();
factoryControl.expectAndReturn(factory.createEntityManager(), manager);
}
@Override
protected void tearDown() throws Exception {
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
}
public void testOpenEntityManagerInterceptorInView() throws Exception {
OpenEntityManagerInViewInterceptor rawInterceptor = new OpenEntityManagerInViewInterceptor();
rawInterceptor.setEntityManagerFactory(factory);
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
MockServletContext sc = new MockServletContext();
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
managerControl.replay();
factoryControl.replay();
interceptor.preHandle(request, response, "handler");
assertTrue(TransactionSynchronizationManager.hasResource(factory));
// check that further invocations simply participate
interceptor.preHandle(request, response, "handler");
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
interceptor.preHandle(request, response, "handler");
interceptor.postHandle(request, response, "handler", null);
interceptor.afterCompletion(request, response, "handler", null);
factoryControl.verify();
managerControl.verify();
managerControl.reset();
factoryControl.reset();
managerControl.replay();
factoryControl.replay();
interceptor.postHandle(request, response, "handler", null);
assertTrue(TransactionSynchronizationManager.hasResource(factory));
factoryControl.verify();
managerControl.verify();
managerControl.reset();
factoryControl.reset();
manager.close();
managerControl.replay();
factoryControl.replay();
interceptor.afterCompletion(request, response, "handler", null);
assertFalse(TransactionSynchronizationManager.hasResource(factory));
factoryControl.verify();
managerControl.verify();
}
public void testOpenEntityManagerInViewFilter() throws Exception {
manager.close();
managerControl.replay();
factoryControl.replay();
MockControl factoryControl2 = MockControl.createControl(EntityManagerFactory.class);
final EntityManagerFactory factory2 = (EntityManagerFactory) factoryControl2.getMock();
MockControl managerControl2 = MockControl.createControl(EntityManager.class);
EntityManager manager2 = (EntityManager) managerControl2.getMock();
factoryControl2.expectAndReturn(factory2.createEntityManager(), manager2);
manager2.close();
factoryControl2.replay();
managerControl2.replay();
MockServletContext sc = new MockServletContext();
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(sc);
wac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", factory);
wac.getDefaultListableBeanFactory().registerSingleton("myEntityManagerFactory", factory2);
wac.refresh();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
MockHttpServletRequest request = new MockHttpServletRequest(sc);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
filterConfig2.addInitParameter("entityManagerFactoryBeanName", "myEntityManagerFactory");
final OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();
filter.init(filterConfig);
final OpenEntityManagerInViewFilter filter2 = new OpenEntityManagerInViewFilter();
filter2.init(filterConfig2);
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
assertTrue(TransactionSynchronizationManager.hasResource(factory));
servletRequest.setAttribute("invoked", Boolean.TRUE);
}
};
final FilterChain filterChain2 = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
throws IOException, ServletException {
assertTrue(TransactionSynchronizationManager.hasResource(factory2));
filter.doFilter(servletRequest, servletResponse, filterChain);
}
};
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
assertFalse(TransactionSynchronizationManager.hasResource(factory));
assertFalse(TransactionSynchronizationManager.hasResource(factory2));
filter2.doFilter(request, response, filterChain3);
assertFalse(TransactionSynchronizationManager.hasResource(factory));
assertFalse(TransactionSynchronizationManager.hasResource(factory2));
assertNotNull(request.getAttribute("invoked"));
factoryControl.verify();
managerControl.verify();
factoryControl2.verify();
managerControl2.verify();
wac.close();
}
}