📄 functionaltestcase.java
字号:
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.junit.functional;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.sql.Connection;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Mappings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.SessionFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.junit.UnitTestCase;
import org.hibernate.engine.SessionFactoryImplementor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Most of the Hibernate test suite in fact is a series of functional tests, not
* unit tests. Here is a base class for these functional tests.
*
* @author Steve Ebersole
*/
public abstract class FunctionalTestCase extends UnitTestCase implements ExecutionEnvironment.Settings {
private static final Logger log = LoggerFactory.getLogger( FunctionalTestCase.class );
private ExecutionEnvironment environment;
private boolean isEnvironmentLocallyManaged;
private org.hibernate.classic.Session session;
public FunctionalTestCase(String string) {
super( string );
}
public ExecutionEnvironment getEnvironment() {
return environment;
}
public void setEnvironment(ExecutionEnvironment environment) {
this.environment = environment;
}
protected void prepareTest() throws Exception {
}
protected void cleanupTest() throws Exception {
}
// JUnit hooks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Override {@link junit.framework.TestCase#setUp()} to check if we need
* to build a locally managed execution environment.
*
* @throws Exception
*/
protected final void setUp() throws Exception {
if ( environment == null ) {
log.info( "Building locally managed execution env" );
isEnvironmentLocallyManaged = true;
environment = new ExecutionEnvironment( this );
environment.initialize();
}
prepareTest();
}
/**
* Override {@link junit.framework.TestCase#tearDown()} to tear down
* the execution environment if it is locally managed.
*
* @throws Exception
*/
protected final void tearDown() throws Exception {
cleanupTest();
if ( isEnvironmentLocallyManaged ) {
log.info( "Destroying locally managed execution env" );
environment.complete();
environment = null;
}
}
/**
* runTest is overridden in order to apply session closure assertions.
*
* @throws Throwable
*/
protected void runTest() throws Throwable {
final boolean stats = sfi().getStatistics().isStatisticsEnabled();
try {
if ( stats ) {
sfi().getStatistics().clear();
}
super.runTest();
if ( stats ) {
sfi().getStatistics().logSummary();
}
if ( session != null && session.isOpen() ) {
if ( session.isConnected() ) {
session.connection().rollback();
}
session.close();
session = null;
fail( "unclosed session" );
}
else {
session = null;
}
assertAllDataRemoved();
}
catch ( Throwable e ) {
log.trace( "test run resulted in error; attempting to cleanup", e );
try {
if ( session != null && session.isOpen() ) {
if ( session.isConnected() ) {
session.connection().rollback();
}
session.close();
}
}
catch ( Exception ignore ) {
}
try {
if ( recreateSchemaAfterFailure() && environment != null ) {
environment.rebuild();
}
}
catch ( Exception ignore ) {
}
throw e;
}
}
protected void assertAllDataRemoved() {
if ( !createSchema() ) {
return; // no tables were created...
}
if ( !Boolean.getBoolean( "hibernate.test.validateDataCleanup" ) ) {
return;
}
Session tmpSession = getSessions().openSession();
try {
List list = tmpSession.createQuery( "select o from java.lang.Object o" ).list();
Map items = new HashMap();
if ( !list.isEmpty() ) {
for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
Object element = iter.next();
Integer l = ( Integer ) items.get( tmpSession.getEntityName( element ) );
if ( l == null ) {
l = new Integer( 0 );
}
l = new Integer( l.intValue() + 1 );
items.put( tmpSession.getEntityName( element ), l );
System.out.println( "Data left: " + element );
}
fail( "Data is left in the database: " + items.toString() );
}
}
finally {
try {
tmpSession.close();
}
catch( Throwable t ) {
// intentionally empty
}
}
}
protected void skipExpectedFailure(Throwable error) {
super.skipExpectedFailure( error );
try {
if ( recreateSchemaAfterFailure() && environment != null ) {
environment.rebuild();
}
}
catch ( Exception ignore ) {
}
}
// ExecutionEnvironment.Settings implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~
public String getBaseForMappings() {
return "org/hibernate/test/";
}
public boolean createSchema() {
return true;
}
public boolean recreateSchemaAfterFailure() {
return true;
}
public void configure(Configuration cfg) {
}
public boolean overrideCacheStrategy() {
return true;
}
public String getCacheConcurrencyStrategy() {
return "nonstrict-read-write";
}
public void afterSessionFactoryBuilt(SessionFactoryImplementor sfi) {
}
public void afterConfigurationBuilt(Mappings mappings, Dialect dialect) {
}
/**
* Intended to indicate that this test class as a whole is intended for
* a dialect or series of dialects. Skips here (appliesTo = false) therefore
* simply indicate that the given tests target a particular feature of the
* checked database and none of the tests on this class should be run for the
* checked dialect.
*
* @param dialect The dialect to be checked.
* @return False if the test class as a whole is specifically targetting
* a dialect (or series of dialects) other than the indicated dialect
* and the test should therefore be skipped in its entirety;
* true otherwise.
*/
public boolean appliesTo(Dialect dialect) {
return true;
}
// methods for subclasses to access environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the factory for this test environment.
*
* @return The factory.
*/
protected SessionFactory getSessions() {
return environment.getSessionFactory();
}
/**
* Get the factory for this test environment, casted to {@link org.hibernate.engine.SessionFactoryImplementor}.
* <p/>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -