spring-test-dbunit icon indicating copy to clipboard operation
spring-test-dbunit copied to clipboard

NPE upon closing connections in DbUnitRunner after tests have run

Open Hellago opened this issue 6 years ago • 2 comments

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 :

  • Java 11
  • JUnit 4.12
  • Spring Batch 4.1.2.RELEASE
  • Spring Core 5.1.8.RELEASE
  • DbUnit 2.5.4

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.

Hellago avatar Jul 08 '19 15:07 Hellago

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:

  • dbUnitDatabaseConnection is the bean name
  • myConnection is the connection defined on the test class

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.

ppodgorsek avatar Jul 21 '19 08:07 ppodgorsek

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);

Hellago avatar Jul 23 '19 13:07 Hellago