-
Notifications
You must be signed in to change notification settings - Fork 38.4k
Introduce explicit Hibernate and/or DbUnit support in the TestContext Framework [SPR-3096] #7783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
nicolas de loof commented I also added those methods for checking results. This makes Hibernate + DBUnit testing really easy : protected IDataSet getDataSet( String resource )
throws Exception
{
IDatabaseConnection connection = getDatabaseConnection();
InputStream stream = getClass().getResourceAsStream( resource );
IDataSet dataSet = new FlatXmlDataSet( stream );
ReplacementDataSet replacementDataSet = new ReplacementDataSet( dataSet );
replacementDataSet.addReplacementObject( "[NULL]", null );
return replacementDataSet;
}
protected void assertEquals( ITable expected, ITable actual )
throws Exception
{
// Ignore columns not present in "expected"
Column[] columns = expected.getTableMetaData().getColumns();
ITable filteredTable = DefaultColumnFilter.includedColumnsTable( actual, columns );
Assertion.assertEquals( expected, filteredTable );
}
protected void assertEquals( ITable expected, String sql )
throws Exception
{
String tableName = expected.getTableMetaData().getTableName();
ITable actual = getDatabaseConnection().createQueryTable( tableName, sql );
assertEquals( expected, actual );
} |
Arnaud Cogoluègnes commented Here is a DbUnit integration that leverages the TestExecutionListener feature of the Spring TestContext Framework. It basically injects a DataSet before each test method. The listener: import javax.sql.DataSource;
import org.dbunit.database.DatabaseDataSourceConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.util.StringUtils;
public class DbUnitExecutionListener implements TestExecutionListener {
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
DataSource dataSource = testContext.getApplicationContext().getBean(DataSource.class);
Resource dataSetResource = getDataSetLocation(testContext);
if(dataSetResource == null) {
dataSetResource = getDefaultDataSetLocation(testContext);
}
if(dataSetResource != null) {
IDataSet dataSet = new FlatXmlDataSet(dataSetResource.getInputStream());
dataSet = decorate(dataSet);
DatabaseDataSourceConnection datasourceConnection = new DatabaseDataSourceConnection(
dataSource
);
DatabaseOperation.CLEAN_INSERT.execute(
datasourceConnection,
dataSet
);
}
}
/**
* Get explicit dataset location, default uses the DataSetLocation annotation.
* @param testContext
* @return
*/
protected Resource getDataSetLocation(TestContext testContext) {
DataSetLocation dsLocation = testContext.getTestInstance().getClass().getAnnotation(DataSetLocation.class);
if(dsLocation != null) {
return new ClassPathResource(dsLocation.value());
}
return null;
}
/**
* Get default dataset location, based on test class name + '-dataset.xml'.
* @param testContext
* @return
*/
protected Resource getDefaultDataSetLocation(TestContext testContext) {
String dataSetLocation = testContext.getTestInstance().getClass().getName();
dataSetLocation = StringUtils.replace(dataSetLocation, ".", "/");
dataSetLocation = "/"+dataSetLocation+"-dataset.xml";
if(getClass().getResourceAsStream(dataSetLocation) != null) {
return new ClassPathResource(dataSetLocation);
}
return null;
}
/**
* Override to modify the dataset (e.g. use DbUnit's ReplacementDataSet for substitution).
* @param dataSet
* @return
*/
protected IDataSet decorate(IDataSet dataSet) {
return dataSet;
}
@Override
public void afterTestClass(TestContext testContext) throws Exception { }
@Override
public void afterTestMethod(TestContext testContext) throws Exception { }
@Override
public void beforeTestClass(TestContext testContext) throws Exception { }
@Override
public void prepareTestInstance(TestContext testContext) throws Exception { }
} Just like the test framework, it uses a default ([TestClass]-dataset.xml) to locate the dataset. To trigger the listener in a test: @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TestExecutionListeners({DbUnitExecutionListener.class,DependencyInjectionTestExecutionListener.class})
public class PrincipesTest {
// test code
} The listener can use the @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TestExecutionListeners({DbUnitExecutionListener.class,DependencyInjectionTestExecutionListener.class})
@DataSetLocation("/my/path/to/dataset.xml")
public class PrincipesTest {
// test code
} |
Sam Brannen commented Have you guys looked at Carbon Five's custom DbUnit TestExecutionListener? Does the |
Sam Brannen commented Please see the Spring Test DbUnit project by Phil Webb and the related blog article. I think you will find that it meets your needs! Regards, Sam |
Sam Brannen commented This issue is superseded by #11259. |
nicolas de loof opened SPR-3096 and commented
I'm using this abstract base test class to test my Hibernate mappings and DAOs. It uses
AbstractTransactionalDataSourceSpringContextTests
to load the HibernateSessionFactory
and adds DbUnit integration to set up the database in an expected state before the test starts.As I've found it really useful I'd like to contribute it.
Affects: 2.0.2
Issue Links:
The text was updated successfully, but these errors were encountered: