ppodgorsek / spring-test-dbunit

Integration between the Spring testing framework and DBUnit
Apache License 2.0
41 stars 6 forks source link

NPE upon closing connections in DbUnitRunner after tests have run #140

Open Hellago opened 5 years ago

Hellago commented 5 years ago

Hello, First, thanks for your contribution to the community.

I get the following error :

08/07/2019 16:59:33 - WARN : Caught exception while invoking 'afterTestMethod' callback on TestExecutionListener [com.github.springtestdbunit.DbUnitTestExecutionListener@224f520c] for test method [public void MyTest.myTestFunction()] and test instance [MyTest@28040a43] | (TestContextManager.java:548)

  • java.lang.NullPointerException
  • com.github.springtestdbunit.DbUnitRunner.afterTestMethod(DbUnitRunner.java:113)
  • com.github.springtestdbunit.DbUnitTestExecutionListener.afterTestMethod(DbUnitTestExecutionListener.java:185)
  • org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:443)
  • org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:94)
  • org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
  • org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
  • org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
  • at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
  • at java.base/java.lang.Thread.run(Thread.java:834)

Adding a test if (testContext.getConnections() != null) solves the problem, but I guess the cause is somewhere else.

I'm using :

Here is my code : dbunit-context.xml :

    <bean id="dbUnitDatabaseConfig" class="com.github.springtestdbunit.bean.DatabaseConfigBean" lazy-init="true">
        <property name="qualifiedTableNames" value="false" />
        <property name="skipOracleRecyclebinTables" value="true" />
    </bean>
    <bean id="dbUnitDatabaseConnection" class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean" lazy-init="true">
        <property name="dataSource" ref="myDataSource" />
        <property name="databaseConfig" ref="dbUnitDatabaseConfig" />
    </bean>

Test class Java :

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
        DbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = { "myConnection" }, dataSetLoader = MyCustomDataSetLoader.class)
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class MyTest {
    // ...
}

If you can't find the cause, can you at least turn the error into a warning ?

Thank you in advance.

ppodgorsek commented 5 years ago

Sorry for the delay.

The NullPointerException is caused by no connection being available in the test context. From what I see above, you are not using the right bean name:

Could you use the same name in both and retry please?

In the meantime, I will adjust the code to avoid the NPE and log a proper message instead.

Hellago commented 5 years ago

My bean "dbUnitDatabaseConnection" is a factory (badly named I agree), not a connection. I had another piece of code specifying the bean "myConnection" :

    <bean id="myConnection" class="org.dbunit.database.DatabaseConnection" lazy-init="true">
        <constructor-arg name="connection" ref="realConnection" />
    </bean>

Messing up with the name gives the following exception at start :

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myConnection2' available

Messing up with the type of the bean gives that error :

java.lang.IllegalArgumentException: Object of class [java.sql.Connection] must be an instance of interface org.dbunit.database.IDatabaseConnection

So I think the cause is somewhere else. Maybe because I handle connections a bit "manually" ?

final QueryDataSet qds = new QueryDataSet(myConnection);
qds.addTable(tableName, sqlQuery);
MyCustomDataSetLoader.save(qds, saveFile);