Giter Site home page Giter Site logo

springtestdbunit / spring-test-dbunit Goto Github PK

View Code? Open in Web Editor NEW
475.0 475.0 239.0 3.37 MB

Integration between the Spring testing framework and DBUnit

Home Page: http://springtestdbunit.github.com/spring-test-dbunit/

License: Apache License 2.0

Java 99.95% CSS 0.05%

spring-test-dbunit's People

Contributors

jdavisonc avatar mehmet-aslan avatar mikecurwen avatar mutyonok avatar mzagar avatar philwebb avatar pyranja avatar sacdroid avatar stijnvanbael avatar the-alchemist avatar toilal avatar vanackej avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-test-dbunit's Issues

Depending on newer versions of Spring.

Spring 4.0.0 was released to GA yesterday (December 12, 2013). I would like to add Spring 4.0.0 as a dependency to my project, but can't right now because of two problems:

  1. spring-test-dbunit depends on Spring 3.0.5, and relies on a method that has since been deprecated and removed in Spring 4.0.0.
  2. An inversion of lines in SpringJUnit4ClassRunner.methodBlock() from Spring Test causes many tests to fail from data not being removed after tests are completed.

If preferred, I can close this and open two tickets.

Bug The First

spring-test-dbunit uses a deprecated method in the constructor of ExtendedContextManager:

getTestContext().markApplicationContextDirty();

markApplicationContextDirty() with no arguments was deprecated in release 3.2.2, and removed in release 4.0.0. This line can be replaced with

getTestContext().markApplicationContextDirty(null); // or some other HierarchyMode

As far as I can tell, this is the only breaking API-related change that prevents spring-test-dbunit from using newer versions of Spring.

Bug The Second

Now for the fun part.

spring-test-dbunit relies on version 3.0.5 of Spring Test (and several other projects under the Spring umbrella). All of the tests pass with version 3.0.5 of Spring Test.

When I tried upgrading to Spring 4.0.0, many of the tests failed. I first assumed that this was because I was trying to upgrade across several major releases, but I spent some time trying to find out why the tests were failing. This is my story.

The first thing I did was to try compare the outputs from running the tests for spring-test-dbunit with Spring 3.0.5 and Spring 4.0.0, but ultimately decided that the differences between versions was too great to get anything useful out of diff-ing logs. So I took a step back.

Next, I tried upgrading spring-test-dbunit to use Spring 3.0.6, then tried to diff the logs. I won't post the complete set of logs here, but I will point out what I saw that I thought was important (and might not actually be important, but it helped me find out where the problem came from).

Here's a snippet of the logs from spring-test-dbunit when I run mvn clean verify and depending on Spring 3.0.5: http://pastebin.com/p1JBkUN7

Here's a snippet of the logs from spring-test-dbunit when I run mvn clean verify and depending on Spring 3.0.6: http://pastebin.com/eJ4zCy9y

The short version of the log dumps is that with Spring Test 3.0.5, Spring enables transactions before DBunit starts inserting data into the database. With Spring 3.0.6, Spring enables transactions after DBunit starts inserting data into the database. What I think that means is that the data inserted by DBunit is happening before the transaction starts before each test method, so data gets stuck in the database after each test and many of the tests fail.

So now that I'd pinned the problem down to two specific, consecutive versions of Spring Test, I decided to see what the differences were. The only difference between Spring Test 3.0.5 and Spring 3.0.6 happened in SpringJUnit4ClassRunner.methodBlock().

The commit that makes this change is here: spring-projects/spring-framework@6fc6a9e#diff-677eaea448b6a1b054564c32524ddf6c

This commit has a ticket reference, which is here: https://jira.springsource.org/browse/SPR-8537

Ultimately, I don't know if this is a bug with spring-test-dbunit or if it's a bug with Spring Test itself. The change is clearly documented by Spring Test as fixing a bug that was instigated by a change in JUnit.

I don't know if this is something that can be fixed elsewhere; I'm not familiar enough with your code base or the Spring Test code base.

Anyway, thanks for the helpful project, and let me know if I can help out in any way!

Issues with MicrosoftSqlDatabaseOperationLookup

Hi - apologies if this is not the correct place to raise this.

I'm using 1.0.1 of spring-test-dbunit and trying to figure out how MicrosoftSqlDatabaseOperationLookup can help me bypass the normal restrictions on IDENTITY columns in MSSQL and allow me to supply PK values in INSERT operations.

Having switched to using the above class as my @DbUnitConfiguration(databaseOperationLookup) implementation I've hit a number of snags:

  • I want one set of data and test classes to work across a mixture of database types (MSSQL, Postgres, Oracle), so hardcoding databaseOperationLookup to MicrosoftSqlDatabaseOperationLookup seems the wrong way to go. On the other hand I can't see a way for my own implementation of DatabaseOperationLookup to adjust behaviour depending on which target database is in use. Is this possible?
  • When I start to use MicrosoftSqlDatabaseOperationLookup, my @DatabaseSetup annotations are causing failures due to Primary Key constraints being violated during INSERTS. Although I am using @DatabaseSetup(type=DatabaseOperation.CLEAN_INSERT), it appears that PK values from test data for different tests are colliding with each other. If I remove the use of MicrosoftSqlDatabaseOperationLookup, the problem goes away.

Any help/advice much appreciated - thanks.

FlatXmlDataSetLoader doesn't allow reading the dtd from the same folder as the xml

I have an XML dataset-big.xml and the associated DTD in src/test/resources/data.
The XML has this header:

<!DOCTYPE dataset SYSTEM "dataset.dtd">

The problem is that dbunit doesn't look for the DTD in the same folder:

org.dbunit.dataset.DataSetException: java.io.FileNotFoundException: <project root>\dataset.dtd (The system cannot find the file specified)
    at org.dbunit.dataset.xml.FlatXmlProducer.produce(FlatXmlProducer.java:378)
    at org.dbunit.dataset.CachedDataSet.<init>(CachedDataSet.java:97)
    at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:110)
    at org.dbunit.dataset.xml.FlatXmlDataSetBuilder.buildInternal(FlatXmlDataSetBuilder.java:264)
    at org.dbunit.dataset.xml.FlatXmlDataSetBuilder.build(FlatXmlDataSetBuilder.java:147)
    at com.github.springtestdbunit.dataset.FlatXmlDataSetLoader.createDataSet(FlatXmlDataSetLoader.java:38)
Caused by: java.io.FileNotFoundException: <project root>\dataset.dtd (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:146)
    at java.io.FileInputStream.<init>(FileInputStream.java:101)
    at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:613)

The solution is to update FlatXmlDataSetLoader to use an URL instead of InputStream:

    protected IDataSet createDataSet(Resource resource) throws Exception {
        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
        return builder.build(resource.getURL());
    }

As a workaround, I've implemented my own loader with this code, but I think it would be nicer to have this as default in FlatXmlDataSetLoader .

@Rule will not work with Spring 3.1

Looks like this is due to a change in the SpringJUnitClassRunner

3.0:
Statement statement = methodInvoker(frameworkMethod, testInstance);
statement = possiblyExpectingExceptions(frameworkMethod, testInstance, statement);
statement = withRulesReflectively(frameworkMethod, testInstance, statement);
statement = withBefores(frameworkMethod, testInstance, statement);
statement = withAfters(frameworkMethod, testInstance, statement);
statement = withPotentialRepeat(frameworkMethod, testInstance, statement);
statement = withPotentialTimeout(frameworkMethod, testInstance, statement);

3.1

            Statement statement = methodInvoker(frameworkMethod, testInstance);
            statement = possiblyExpectingExceptions(frameworkMethod, testInstance, statement);
            statement = withBefores(frameworkMethod, testInstance, statement);
            statement = withAfters(frameworkMethod, testInstance, statement);
            statement = withRulesReflectively(frameworkMethod, testInstance, statement);
            statement = withPotentialRepeat(frameworkMethod, testInstance, statement);
            statement = withPotentialTimeout(frameworkMethod, testInstance, statement);

Using dbunit-datasetbuilder

HI, I m trying to create IDataSet programatically instead of xml datasets. For that I m using https://github.com/opensource21/dbunit-datasetbuilder (or https://github.com/marcphilipp/dbunit-datasetbuilder). How ever, the assertion fails.

Below is the code:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "/services-test-context.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, TransactionDbUnitTestExecutionListener.class })
@DatabaseSetup("/dummydata.xml") // without some valid file path, test is failing!
@DbUnitConfiguration(dataSetLoader = DBUnitTest.LaunguageDataSetLoader.class)
public class DBUnitTest {

    @Test
    @ExpectedDatabase(value = "/datasets/testdata.xml", table = "language")
    public void test() {
        System.out.println("Success");
    }

    public static class LaunguageDataSetLoader extends AbstractDataSetLoader {

        @Override
        protected IDataSet createDataSet(Resource resource) throws Exception {
            DataSetBuilder builder = new DataSetBuilder();

            builder.newRow("language").with("id", 12).with("version", 0).with("name", "English").add();

            return builder.build();
        }

    }

}

As my dataset comes from the LaunguageDataSetLoader class, I wanted to NOT to give any dataset.xml path to @DatabaseSetup. But this annotation mandates something for value. When I've given empty string, like @DatabaseSetup(""), it is giving me other exceptions.

To work around this, I m giving dummydata.xml like below:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
</dataset>

If I leave the @DatabaseSetup annotation, I m getting junit.framework.ComparisonFailure: row count (table=language) expected:<[1]> but was:<[0]> failure. I think this is expected only.

Basically, my objective is to provide dataset from with in the class (this will avoid the need for ReplacementDataSet for currenttime or null, ...).

My question is, can we not make the value of the annotation optional, and also why is the annotation is supported at class level. Even better, having dataSetLoader support at @DatabaseSetup level itself instead of @DbUnitConfiguration.

Exporting data into XML file

Is there an annotation that can be used to export data in a particular database table into an XML file?

This would be useful, when I need to backup data, put in test data and when done with my tests put back the backed up data.

Transaction committed during setup

When using MS SQL Server and InsertIdentityOperation DBUnit commits transactions in the execute method so Spring rollback annotations don't work. In this case it's not enough to wrap the datasource with TransactionAwareDataSourceProxy in DatabaseDataSourceConnectionFactoryBean but also disable commits.

DatabaseAssertionMode.NON_STRICT won't work if the expected data set includes its dtd file

Let assume that the dtd file has all columns defined. And I included that dtd file inside my expected data set as I wanted auto-completion and validation. Suddenly, all of my test cases declared as NON_STRICT failed. When I debugged into the spring-test-dbunit source code, I found out the array ignoredColumns in the method NonStrictDatabaseAssertion.assertEquals was empty. Eventually, I removed the dtd inclusion, these just failed test cases worked again.

Is there a way to get expected data sets validated without giving up NON_STRICT mode?

How to configure datatypeFactory for the Custom IDatabaseConnections?

I need to config the datatypeFactory(eg:MysqlDataTypeFactory) inside of the applicationContext.xml of dbUnitDatabaseConfig, could you tell me how to config it into the below configurations?Thanks

Custom IDatabaseConnections

<bean id="dbUnitDatabaseConfig" class="com.github.springtestdbunit.bean.DatabaseConfigBean">
    <property name="skipOracleRecyclebinTables" value="true"/>
</bean>
<bean id="dbUnitDatabaseConnection" class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean">
    <property name="databaseConfig" ref="dbUnitDatabaseConfig"/>
</bean>

Error with multiple source files containing different tables.

I have two xml files containing data for different tables. I get an error when I run multiple tests using CLEAN_INSERT as DatabaseOperation.

I have traced the error to the method setupOrTeardown in class DbUnitRunner. The outer loop runs once when a test is setup since a @DatabaseSetup annotation is detected on my class. The inner loop then runs twice, one for each xml file. The first test always passes but when it is time for the second test this will happend:
1 In the first iteration of the inner loop dbUnitDatabaseOperation will be a CompositeOperation, clean and insert, and it will execute.
2 lastOperation will be set to CLEAN_INSERT
3 The second iteration of the inner loop will execute now working with the sexcond xml file.
4 Since lastOperation is CLEAN_INSERT dbUnitDatabaseOperation will now become an InsertOperation and not a CompositeOperation.
5 The data in the second file will be inserted before the tables in that file has been cleared.
6 A unique constraint error is thrown.

I cloned the repository and tried to recreate this error in the tests but I failed even If I verified through debugging that at least step 1-4 is the same. Somehow, no error is thrown. I don't know what can differ from my setup and the test setup. The only thing I found was that the tests let hibernate automatically create and drop table. I do not do this in my setup. My tables are created through generated sql files.

java.lang.NoClassDefFoundError: org/dbunit/database/IDatabaseConnection while using @DbUnitConfiguration

Just trying to use a different data source name:

    <!--jee:jndi-lookup id="oracleDataSource" jndi-name="java:comp/env/${jndi-oracle}" /-->
    <!--jee:jndi-lookup id="postgreSqlDataSource" jndi-name="java:comp/env/${jndi-postgresql}" /-->
    <bean id="postgreSqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="${jdbc.postgresql.url}" />
        <property name="username" value="${jdbc.postgresql.username}" />
        <property name="password" value="${jdbc.postgresql.password}" />
    </bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-jpa.xml")
@DbUnitConfiguration(databaseConnection = "postgreSqlDataSource")
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    DbUnitTestExecutionListener.class})
public class EntidadeRepositoryTest {

    @Autowired
    IAtoLegalRepository atoLegalRepository;

    @Autowired
    IEntidadeRepository entidadeRepository;


    @Test
    @DatabaseSetup("entidade-data.xml")
    public void findOne() {
        Entidade secad = entidadeRepository.findOne(1);
        Assert.assertNotNull(secad);
        Assert.assertEquals("secad", secad.getNome());
    }
}

The exception:

Running br.gov.to.secad.sapeo.repository.EntidadeRepositoryTest
15:28:50.415 [main] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 5.0.2.Final
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.094 sec <<< FAILURE! - in br.gov.to.secad.sapeo.repository.EntidadeRepositoryTest
findOne(br.gov.to.secad.sapeo.repository.EntidadeRepositoryTest)  Time elapsed: 3.738 sec  <<< ERROR!
java.lang.NoClassDefFoundError: org/dbunit/database/IDatabaseConnection
    at com.github.springtestdbunit.DbUnitTestExecutionListener.prepareDatabaseConnection(DbUnitTestExecutionListener.java:133)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.prepareTestInstance(DbUnitTestExecutionListener.java:113)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:326)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: java.lang.ClassNotFoundException: org.dbunit.database.IDatabaseConnection
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.prepareDatabaseConnection(DbUnitTestExecutionListener.java:133)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.prepareTestInstance(DbUnitTestExecutionListener.java:113)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:326)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)

Can't Use InsertIdentityOperation

When executing integration tests against a MS SQL Server 2008 instance, I need to be able to use the org.dbunit.ext.mssql.InsertIdentityOperation so that I can insert on identity columns. This operation executes the "SET IDENTITY_INSERT

ON" statement that enables this.

The current spring-test-dbunit framework does not map this operation in com.github.springtestdbunit.DbUnitRunner and I am not provided with a way to add the mapped operation.

Setup database once per whole test class

Hi Phillip, Mario.
I use spring-test-dbunit on most of my projects.
I like its declarative approach and how it reduces amount of boilerplate code.

Though, spring-test-dbunit lacks ability to perform database setup only once for the whole test class.
Often it is required to test some read-only dao. Performing database setup in separate transaction before each test method would require very long time (depending on dataset size and current database state).

In my fork I've added POC implementation of such feature. It is implemented via dedicated TestExecutionListener and reuses existing annotations.

https://github.com/edio/spring-test-dbunit/commit/5023c0b82b38f6ab262063e57cb7dffda269083c

I would like to know, what do you think about such feature in general. Is there any chance you could consider adding it to your framework?
Also, let me know, please, what do you think about my current approach. I'm eager to contribute to your project and would appreciate any comments/suggestions.

Thanks.

Spring container couldn't initialize when @DbUnitConfiguration is in use

I tried to use datasetLoader of @DbUnitConfiguration, and not declare the attribute databaseConnetion. Then I received an exception when the Spring container was initializing. I figured out it's caused by an empty string as the default value of databaseConnection attribute.

        if (configuration != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Using @DbUnitConfiguration configuration");
            }
            databaseConnectionBeanNames = configuration.databaseConnection(); // default value is an empty string
            dataSetLoaderClass = configuration.dataSetLoader();
            dataSetLoaderBeanName = configuration.dataSetLoaderBean();
            databaseOperationLookupClass = configuration.databaseOperationLookup();
        }


        if (ObjectUtils.isEmpty(databaseConnectionBeanNames))  // that snippet couldn't be executed as the array had an empty string
       { 
            databaseConnectionBeanNames = new String[] { getDatabaseConnectionUsingCommonBeanNames(testContext) };
        }

Spring 3.x.x issue with TestContext

You've changed usage of testContext to be reflection based but if logger.isDebugEnabled returns true you use testContext variable in direct way (direct method call). So here you will have an exception something like "TestContext found class but expected an interface..."

DbUnitTestExecutionListener.java
line 86:
if (logger.isDebugEnabled()) {
86: logger.debug("Preparing test instance " + testContext.getTestClass() + " for DBUnit");
}

Multiple datasource support

I'm curious, whether you may implement multiple datasource support. I have forked your project and tried to give that support which we can provide datasource files (xmls) to different datasources. Although some tests related to @transactional are failing right now, maybe you want to check out mine. The usage is simply;

@DbUnitConfiguration(connections="conn1,conn2")
@DatabaseSetup(connections = {@DatabaseConnectionSetup(connection="conn1", value="xxx.xml")})

This project doesn't build

It comes up with this error:
Cannot find parent: org.objenesis:objenesis-parent for project: org.objenesis:objenesis:jar:1.0 for project org.objenesis:objenesis:jar:1.0

DbUnitTestExecutionListener swallows test exceptions and performs dbunit test anyway

See sample code bellow: if repo.store() call throws exception, DbUnitTestExecutionListener will ignore it and will perform @ExpectedDatabase test. It would be better to re-throw test exception if it happens and never do any dbunit tests.

@Test
@ExpectedDatabase(value="inbound_test_store.xml")
public void test_store_must_succeed() {
    repo.store(new Model(0L, "x1, "x2, null));
}

Warn of The configured data type factory ‘class org.dbunit.dataset.datatype.DefaultDataTypeFactory’ might cause problems with the current database

Hi Phillip, Mario.
I'm trying to use spring-test-dbunit on most of my projects, it provides a lot of essential features, but it always alerts a warning in my Unit tests with this message:

Warning:
Potential problem found: The configured data type factory ‘class
org.dbunit.dataset.datatype.DefaultDataTypeFactory’ might cause
problems with the current database ‘MySQL’ (e.g. some datatypes may
not be supported properly). In rare cases you might see this message
because the list of supported database products is incomplete
(list=[derby]). If so please request a java-class update via the
forums.If you are using your own IDataTypeFactory extending
DefaultDataTypeFactory, ensure that you override getValidDbProducts()
to specify the supported database products.

I checked the source codes(using version 1.2.1), and found the warning might caused by:

DbUnitTestExecutionListener class

    private void prepareDatabaseConnection(DbUnitTestContextAdapter testContext, String[] connectionBeanNames)
            throws Exception {
        ...
        Object databaseConnection = testContext.getApplicationContext().getBean(connectionBeanNames[i]);
        if (databaseConnection instanceof DataSource) {
            databaseConnection = DatabaseDataSourceConnectionFactoryBean
                    .newConnection((DataSource) databaseConnection);
        }
        Assert.isInstanceOf(IDatabaseConnection.class, databaseConnection);
        ...
    }

So it means that the databaseConnection will be created from DatabaseDataSourceConnectionFactoryBean.newConnection, and so finally I found DatabaseDataSourceConnectionFactoryBean's getObject method:

    public DatabaseDataSourceConnection getObject() throws Exception {
        Assert.notNull(this.dataSource, "The dataSource is required");
        DatabaseDataSourceConnection dataSourceConntection = new DatabaseDataSourceConnection(
                makeTransactionAware(this.dataSource), this.schema, this.username, this.password);
        if (this.databaseConfig != null) {
            this.databaseConfig.apply(dataSourceConntection.getConfig());
        }
        return dataSourceConntection;
    }

I think the dataSourceConntection.getConfig() can't get any value, as it should be fetched from the spring's beans.

So could you help me to take a look at this issue? thanks.

@ExpectedDatabases can't work when using multiple datasources

I got an issue when using @ExpectedDatabases like this:

@Test
@DatabaseSetup(connection = DataSourceKeys.DATA_SOURCE_1, value = "AfterUpdateDataSource1.xml")
@DatabaseSetup(connection = DataSourceKeys.DATA_SOURCE_2, value = "AfterUpdateDataSource2.xml")
@ExpectedDatabases({
        @ExpectedDatabase(connection = DataSourceKeys.DATA_SOURCE_1, value = "AfterUpdateNotNullDataSource1.xml", assertionMode = DatabaseAssertionMode.NON_STRICT),
        @ExpectedDatabase(connection = DataSourceKeys.DATA_SOURCE_2, value = "AfterUpdateNotNullDataSource2.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
    })

I suppose the ExpectedDatabases annotation can be works for two datasources but, only one annotation (DATA_SOURCE_2) can work, could you help take a look at this issue?

@Transactional leads an exception: connection does not exist

I am using spring-test-dbunit with spring-test to test the dao layer. The following code will leads a "connection does not exist "

@Transactional
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionDbUnitTestExecutionListener.class})
public class UserDaoTest{
}

I debug and found that caused by the order of CHAIN members in TransactionDbUnitTestExecutionListener:

private static final Class<?>[] CHAIN = { TransactionalTestExecutionListener.class,
            DbUnitTestExecutionListener.class };

I fixed it as below:

private static final Class<?>[] CHAIN = { DbUnitTestExecutionListener.class, TransactionalTestExecutionListener.class };

Caught exception while allowing TestExecutionListener [com.github.springtestdbunit.TransactionDbUnitTestExecutionListener] ...

I have this simple junit test class:

@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionDbUnitTestExecutionListener.class,
    DbUnitTestExecutionListener.class })
@DatabaseSetup(value = "classpath:person-sample-data.xml", type = DatabaseOperation.CLEAN_INSERT)
@TransactionConfiguration
@DbUnitConfiguration(databaseConnection = "dataSource")
public class PersonTest {

@PersistenceContext
EntityManager em;

@Transactional
@Test
public void testSavePersonEM() {
    logger.info("--- testSavePersonEM ---");
    Person person = new Person("Vladimir", "Jankovic");
    person.setAddress("Starca Vujadina 27");
    person.setEmail("[email protected]");

    logger.info("Before persist ...");

    // em.joinTransaction();
    em.persist(person);
    em.flush();

    logger.info("new id:" + person.getId());
}

}

I'm not sure if this is DBunit problem, Spring problem, or something is wrong else but I'm getting the following error:

2013-10-20 11:55:17,910 WARN [org.springframework.test.context.TestContextManager] - Caught exception while allowing TestExecutionListener [com.github.springtestdbunit.TransactionDbUnitTestExecutionListener@2c8c3540] to process 'after' execution for test: method [public void org.ndsys.dentalrec.domain.PersonTest.testLoadPersonWithoutRecords()], instance [org.ndsys.dentalrec.domain.PersonTest@28fc1399], exception [null]
org.springframework.transaction.TransactionSystemException: Could not roll back JPA transaction; nested exception is javax.persistence.PersistenceException: unexpected error when rollbacking
    at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:543) ~[spring-orm-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:846) ~[spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:823) ~[spring-tx-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:588) ~[spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:297) ~[spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:192) ~[spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at com.github.springtestdbunit.TestExecutionListenerChain$4.call(TestExecutionListenerChain.java:100) ~[spring-test-dbunit-1.0.1.jar:na]
    at com.github.springtestdbunit.TestExecutionListenerChain.runChain(TestExecutionListenerChain.java:125) ~[spring-test-dbunit-1.0.1.jar:na]
    at com.github.springtestdbunit.TestExecutionListenerChain.backwards(TestExecutionListenerChain.java:118) ~[spring-test-dbunit-1.0.1.jar:na]
    at com.github.springtestdbunit.TestExecutionListenerChain.afterTestMethod(TestExecutionListenerChain.java:98) ~[spring-test-dbunit-1.0.1.jar:na]
    at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:395) ~[spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:91) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) [spring-test-3.2.4.RELEASE.jar:3.2.4.RELEASE]
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) [.cp/:na]
Caused by: javax.persistence.PersistenceException: unexpected error when rollbacking
    at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:109) ~[hibernate-entitymanager-4.2.6.Final.jar:4.2.6.Final]
    at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:539) ~[spring-orm-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    ... 29 common frames omitted
Caused by: org.hibernate.TransactionException: rollback failed
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:215) ~[hibernate-core-4.2.6.Final.jar:4.2.6.Final]
    at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:106) ~[hibernate-entitymanager-4.2.6.Final.jar:4.2.6.Final]
    ... 30 common frames omitted
Caused by: org.hibernate.TransactionException: unable to rollback against JDBC connection
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:167) ~[hibernate-core-4.2.6.Final.jar:4.2.6.Final]
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:209) ~[hibernate-core-4.2.6.Final.jar:4.2.6.Final]
    ... 31 common frames omitted
Caused by: java.sql.SQLNonTransientConnectionException: connection exception: connection does not exist
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hsqldb.jdbc.JDBCUtil.connectionClosedException(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hsqldb.jdbc.JDBCConnection.checkClosed(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hsqldb.jdbc.JDBCConnection.rollback(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:163) ~[hibernate-core-4.2.6.Final.jar:4.2.6.Final]
    ... 32 common frames omitted
Caused by: org.hsqldb.HsqlException: connection exception: connection does not exist
    at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.3.0.jar:2.3.0]
    ... 37 common frames omitted

@DatabaseTearDown doesn't work when @ExpectedDatabase fails.

I have the following setup:

@DatabaseTearDown("/resetDB.xml")
public class CSVConfigTests {

    @Test
    @ExpectedDatabase(assertionMode = DatabaseAssertionMode.NON_STRICT, value = "dataVerificationTest.xml")
    public void shouldImportCSV() throws Exception {
        // db imports
    }
}

when shouldImportCSV fails due to @ExpectedDatabase assertion, @DatabaseTearDown doesn't work as data still remains in database. Is this by design or a bug?

Failure of tearDown causes other tests to fail as well.

DbUnitRule swallows test errors

com.github.springtestdbunit.DbUnitRule.DbUnitStatement.evaluate(void) method swallows test errors. Sample code below passes the test because DbUnitRule.DbUnitStatement.evaluate(void) method swallows the assertion error.

public class SampleTest {
    @Rule
    public DbUnitRule dbUnit = new DbUnitRule();

    @Test
    public void testMethod() {
        Assert.assertTrue("Assertion failed.", false);
    }
}

Patch below fixes the problem. Patch has been generated on the master branch downloaded at 2013-05-19 14:41:00 GMT +05:30.

--- spring-test-dbunit-master/spring-test-dbunit/src/main/java/com/github/springtestdbunit/DbUnitRule.java  2013-03-12 10:21:36.000000000 +0530
+++ spring-test-dbunit-master-fixed/spring-test-dbunit/src/main/java/com/github/springtestdbunit/DbUnitRule.java    2013-05-19 15:43:38.000000000 +0530
@@ -210,6 +210,10 @@
                this.testContext.setTestException(e);
            }
            runner.afterTestMethod(this.testContext);
+
+           if (testContext.getTestException() != null) {
+               throw testContext.getTestException();
+           }
        }
    }

Support for ignored columns

[Change Request]

I think it would be nice to allow ignoring configured columns on @ExpectedDatabase validation. DBUnit supports it.

It's specially usefull when working with IDENTITY type fields or secuence generated fields.

Transaction & ExceptedDatabase Annotations Execution Order

Hello @philwebb,
I'm using spring-test-dbunit 1.0.0, and I'm writing unit tests at repository(DAO) layer with tranasction. When I test it, it always get errors becourse of the excution order:
"Transactions start before @DatabaseSetup and end after @DatabaseTearDown and @ExpectedDatabase. "
In my case, I need Transaction start after @DatabaseSetup and end before @DatabaseTearDown. is that possible? Please see the code:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
@Transactional
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, 
    DirtiesContextTestExecutionListener.class, 
    TransactionDbUnitTestExecutionListener.class })
@TransactionConfiguration(defaultRollback = false)
public class DepartmentDaoJpaImplWithSprintTestDBUnitTest {

    @Autowired
    private DepartmentDao departmentDao;

    @Test
    @DatabaseSetup("DepartmentDaoJpaImplWithSprintTestDBUnitTest.shouldSuccessfullyUpdateDepartment.xml")
   @ExpectedDatabase("DepartmentDaoJpaImplWithSprintTestDBUnitTest.shouldSuccessfullyUpdateDepartment.expected.xml")
    public void shouldSuccessfullyUpdateDepartment() {
        Department department = departmentDao.find(2L);
        department.setName("Test Update");
        departmentDao.update(department);
    }
}

@ExpectedDatabase NON_STRICT tests

Hi Phil,

Could you please take a look at ExpectedNonStrictOnClassTest and ExpectedNonStrictOnMethodTest tests?

I believe ExpectedFailureOnClassTest is missing 'assertionMode=NON_STRICT' in @ExpectedDatabase and wrong dataset XML file is used (expectedfail.xml, but should be expected_nonstrict.xml).

Also, shouldn't both those tests use DbUnitTestExecutionListener so DbUnitRunner.afterTestMethod() actually executes?
(when I put a breakpoint in DbUnitRunner.afterTestMethod() and debug the unit test, bp never hits...)

My idea for both unit tests was that entityAssert.assertValues() should pass normally, but if NON_STRICT assertion mode is not set, then dbunit assertion should fail when checking against expected_nonstrict.xml dataset (since not all columns are specified in the XML file).

Am I getting something wrong here? Should I be thinking about these tests differently?

Regards,
Mario

TestContext extracted to interface in Spring 4

Upgrading tests from Spring 3.2.6 (all worked well) to Spring 4.0.0, recently released, an error arises:
java.lang.IncompatibleClassChangeError: Found interface org.springframework.test.context.TestContext, but class was expected
at com.github.springtestdbunit.TestExecutionListenerChain.runChain(TestExecutionListenerChain.java:134) ~[spring-test-dbunit-1.0.1.jar:na]

This is due to the fact that the TestContext is now an interface, so the DefaultTestContext (or another implementation) should be fed to the chain

@ExpectedDatabase and null dates

I am using HSQLDB with Hibernate to unit test. When I want to set a date to null in the database, dbunit throws
org.dbunit.dataset.datatype.TypeCastException: Unable to typecast value <[NULL]> of type <java.lang.String> to TIMESTAMP.

Is there any value in @ExpectedDatabase that will resolve to NULL? Example:

Trouble using DatabaseSetup

When I use the @DatabaseSetup annotation, loading a scenario from XML file, the CleanInsert is not performed.

I use the 1.0.0 version of spring-test-dbunit and 4.1.1.RELEASE of the Spring Framework.

Provide a way to replace tokens in the data set with values generated in test runtime.

Look at the most voted answer for the following post

http://stackoverflow.com/questions/2856840/date-relative-to-current-in-the-dbunit-dataset

I'm imaging something like this:

@Before
public void onSetup(@DatabaseSetupRelatedAnnotation ReplacementDataSet replacementDataSet){}
@Test
@DatabaseSetup("initDataset.xml")
@ExpectedDatabase("expectedDataset.xml")
public void testXX(@ExpectedDatabaseRelatedAnnotation ReplacementDataSet replacementDataSet){}

I remember seeing BDD frameworks before like cucumber injecting values in test method arguments.

assertEqualsByQuery

Do you have any plans to add functionality that would wrap DBUnit assertEqualsByQuery?

DatabaseOperation.NONE

DatabaseOperation.NONE operation of DBUnit don't exist.

There is no chance to make an CompositeOperation on @DatabaseSetup and @DatabaseTearDown

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.