Skip to content

Instantly share code, notes, and snippets.

@aeris
Created February 7, 2013 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aeris/4730976 to your computer and use it in GitHub Desktop.
Save aeris/4730976 to your computer and use it in GitHub Desktop.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DbSchema {
String value();
}
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.dataset.datatype.IDataTypeFactory;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.junit.After;
import org.junit.Before;
/**
* Classe de gestion des tests ayant besoin d'une base de données.
*/
public abstract class DbTestCase extends TestCase {
/**
* Clef de la propriété de la factory de la base de données.<br/>
* Dépend du moteur de base utilisé (ici H2).
*/
private static final String DB_FACTORY = "dbunit.factory";
/**
* Connexion à la base de données.
*/
private DatabaseConnection connection;
/**
* Hibernate session factory.
*/
@Autowired
protected SessionFactory sessionFactory;
/**
* Transaction Hibernate.
*/
private Transaction transaction;
/**
* Retourne la session Hibernate courante.
*
* @return Session Hibernate
*/
public Session getSession() {
return this.sessionFactory.getCurrentSession();
}
/**
* Crée une nouvelle transaction.
*
* @throws Exception
* Levée en cas d'erreur en base de données
*/
public void restart() throws Exception {
this.tearDown();
this.setUp();
}
/**
* Crée une transaction Hibernate pour chaque test.
*
* @throws Exception
* Levée en cas d'erreur en base de données
*/
@Before
public void setUp() throws Exception {
this.transaction = this.getSession().beginTransaction();
}
/**
* Commit la transaction à la fin de chaque test.
*/
@After
public void tearDown() {
this.commit();
}
/**
* Commit la transaction.
*/
protected void commit() {
if (this.transaction.isActive()) {
this.transaction.commit();
}
}
/**
* Annule la transaction.
*/
protected void rollback() {
if (this.transaction.isActive()) {
this.transaction.rollback();
}
}
/**
* Crée une connexion à la base de données à partir des différentes
* configurations (Hibernate, moteur de base de données...).
*
* @return Connexion à la base de données
* @throws DatabaseUnitException
* Levée en cas d'erreur lors de la création de la connexion
*/
private DatabaseConnection getConnection() throws DatabaseUnitException {
if (this.connection == null) {
try {
final DriverManagerDataSource dbSource =
(DriverManagerDataSource) ApplicationContextHandler
.getContext().getBean("dataSource");
final Connection jdbcConnection =
DriverManager.getConnection(dbSource.getUrl(),
dbSource.getUsername(), dbSource.getPassword());
final DbSchema annotationSchema =
this.getClass().getAnnotation(DbSchema.class);
if (annotationSchema == null) {
this.connection = new DatabaseConnection(jdbcConnection);
} else {
this.connection =
new DatabaseConnection(jdbcConnection,
annotationSchema.value());
}
final InputStream conf =
DbTestCase.class
.getResourceAsStream("/dbunit.properties");
final Properties props = new Properties();
try {
props.load(conf);
} finally {
conf.close();
}
if (props.containsKey(DB_FACTORY)) {
@SuppressWarnings("unchecked")
final Class<IDataTypeFactory> c =
(Class<IDataTypeFactory>) Class.forName(props
.getProperty(DB_FACTORY));
final Constructor<IDataTypeFactory> cons =
c.getConstructor();
this.connection.getConfig().setProperty(
DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
cons.newInstance());
}
this.connection.getConfig().setProperty(
DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
} catch (final Exception e) {
throw new DatabaseUnitException(e);
}
}
return this.connection;
}
/**
* Charge un dataset en base de données.
*
* @param dataset
* Dataset XML
* @param operation
* Opération à effectuer sur la base (chargement, nettoyage...)
* @throws DatabaseUnitException
* Levée en cas d'erreur lors du chargement
*/
private void load(final InputStream dataset,
final DatabaseOperation operation) throws DatabaseUnitException {
try {
operation.execute(this.getConnection(),
new FlatXmlDataSetBuilder().build(dataset));
} catch (final SQLException e) {
throw new DatabaseUnitException(e);
}
}
/**
* Charge un dataset en base de données.
*
* @param dataset
* Chemin d'accès au dataset XML
* @param operation
* Opération à effectuer sur la base (chargement, nettoyage...)
* @throws DatabaseUnitException
* Levée en cas d'erreur lors du chargement
* @throws IOException
*/
protected void load(final String dataset, final DatabaseOperation operation)
throws DatabaseUnitException, IOException {
final InputStream datas = this.getClass().getResourceAsStream(dataset);
try {
this.load(datas, operation);
} finally {
datas.close();
}
}
/**
* Charge un dataset en base de données.
*
* @param dataset
* Chemin d'accès au dataset XML
* @throws DatabaseUnitException
* Levée en cas d'erreur lors du chargement
* @throws IOException
*/
protected void load(final String dataset) throws DatabaseUnitException,
IOException {
this.load(dataset, DatabaseOperation.CLEAN_INSERT);
}
/**
* Charge un dataset en base de données pour nettoyer la base.
*
* @param dataset
* Chemin d'accès au dataset XML
* @throws DatabaseUnitException
* Levée en cas d'erreur lors du chargement
* @throws IOException
*/
protected void clean(final String dataset) throws DatabaseUnitException,
IOException {
this.load(dataset, DatabaseOperation.DELETE_ALL);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment