PDA

View Full Version : TestNg Integration Test can't load SQL resource



whosrodney
Feb 4th, 2010, 08:05 PM
Hi all,

I'm having some trouble trying to put together a TestNG integration test. I'm trying to connect to an HSQLDB database to load a couple of rows in order to test some DAO classes. The test is as follows:



@ContextConfiguration(locations = { "classpath:test-context.xml" })
public class JdbcProductDaoTest extends
AbstractTransactionalTestNGSpringContextTests {

private ProductDao productDao;

public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}

@BeforeTest
public void onSetUpInTransaction() {
// super.deleteFromTables(new String[] {"products"});
super.executeSqlScript("classpath:load-data.sql", false);
}

@Test
public void testGetProductList() {

List<Product> products = productDao.getProductList();

assert 3 == products.size();
}

@Test
public void testSaveProduct() {

List<Product> products = productDao.getProductList();

for (Product p : products) {
p.setPrice(200.12);
productDao.saveProduct(p);
}

List<Product> updatedProducts = productDao.getProductList();
for (Product p : updatedProducts) {
assert 200.12 == p.getPrice();
}

}

}

test-context.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<!--
the test application context definition for the jdbc based tests
-->

<bean id="productDao" class="nu.rro.repository.JdbcProductDao">
<property name="dataSource" ref="dataSource" />
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerD ataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:db/testdb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyP laceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:jdbc.properties</value>
</list>
</property>
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTran sactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

</beans>

I'm building the project using Maven. test-context.xml lives under src/test/resources, as does the SQL file I'm trying to load (load-data.sql).

The error I get when I try to run the test is:


FAILED CONFIGURATION: @BeforeTest onSetUpInTransaction
java.lang.NullPointerException
at org.springframework.test.context.testng.AbstractTr ansactionalTestNGSpringContextTests.executeSqlScri pt(AbstractTransactionalTestNGSpringContextTests.j ava:131)
at nu.rro.repository.JdbcProductDaoTest.onSetUpInTran saction(JdbcProductDaoTest.java:25)

I'm guessing it can't find the SQL file for some reason. Any help would be appreciated :)

whosrodney
Feb 5th, 2010, 04:53 PM
I managed to get my tests to succeed by manually getting the productDao bean from the ApplicationContext (first line of onSetUpInTransaction() below).

JdbcProductDaoTest.java

@ContextConfiguration(locations = { "classpath:test-context.xml" })
public class JdbcProductDaoTest extends
AbstractTransactionalTestNGSpringContextTests {

private ProductDao productDao;

public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}

@BeforeMethod
public void onSetUpInTransaction() {
this.productDao = (ProductDao) this.applicationContext.getBean("productDao");

super.deleteFromTables(new String[] {"products"});
super.executeSqlScript("classpath:load-data.sql", false);
}

@Test
public void testGetProductList() {

List<Product> products = productDao.getProductList();

assert 3 == products.size();
}

@Test
public void testSaveProduct() {

List<Product> products = productDao.getProductList();

for (Product p : products) {
p.setPrice(200.12);
productDao.saveProduct(p);
}

List<Product> updatedProducts = productDao.getProductList();
for (Product p : updatedProducts) {
assert 200.12 == p.getPrice();
}

}

}

test-context.xml

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

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<!--
the test application context definition for the jdbc based tests
-->

<bean id="productDao" class="nu.rro.repository.JdbcProductDao">
<property name="dataSource" ref="dataSource" />
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerD ataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:db/testdb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTran sactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

</beans>

If I don't manually retrieve and set the productDao bean, my tests fail with a NullPointerException.

Any ideas why the productDao bean isn't being injected into my test class?

Sam Brannen
Feb 6th, 2010, 09:01 AM
Any ideas why the productDao bean isn't being injected into my test class?

Yes: you need to use @Autowired on either the productDao instance variable or the corresponding setter method.

See the examples in the Testing chapter of the Spring Reference Manual (http://static.springsource.org/spring/docs/2.5.x/reference/testing.html#testcontext-fixture-di) for details.

Regards,

Sam

whosrodney
Feb 7th, 2010, 03:06 PM
Awesome, thanks for your help Sam :)