NullPointerException when running unit test for Postgres database with Unitils

I have the following table (migration):

databaseChangeLog: - changeSet: id: 1 author: me changes: - createTable: tableName: person columns: - column: name: id type: int autoIncrement: true constraints: primaryKey: true nullable: false - column: name: first_name type: varchar(255) constraints: nullable: false - column: name: last_name type: varchar(255) constraints: nullable: false - changeSet: id: 2 author: me changes: - insert: tableName: person columns: - column: name: first_name value: First - column: name: last_name value: Last 

And the following DAO:

 public interface HelloDao { @SqlQuery( "SELECT * FROM person" ) @Mapper(PersonMapper.class) Person getPerson(); } 

With the following + mapper objects:

 public class Person { private String firstName; private String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } 

-

 public class PersonMapper implements ResultSetMapper<Person> { public Person map(int index, ResultSet r, StatementContext ctx) throws SQLException { return new Person(r.getString("first_name"), r.getString("last_name")); } } 

I use junit and unitils to write unit test for this Dao. I have a unitils.properties file configured like this:

 database.driverClassName=org.postgresql.Driver database.url=jdbc:postgresql://localhost:5432/springbootdb database.dialect=postgresql database.userName=<username> database.password=<password> database.schemaNames=public 

Just for clarity, this application.properties file:

 spring.thymeleaf.cache=false spring.main.show-banner=false logging.level.jdbc=OFF logging.level.jdbc.sqltiming=DEBUG logging.level.jdbc.resultsettable=DEBUG spring.datasource.url= jdbc:postgresql://localhost:5432/springbootdb spring.datasource.username=<username> spring.datasource.password=<password> spring.jpa.hibernate.ddl-auto=create-drop 

Here is my test:

 @Transactional(TransactionMode.ROLLBACK) @RunWith(UnitilsBlockJUnit4ClassRunner.class) public class HelloDaoTest { @TestDataSource DataSource dataSource; private DBI dbi; private HelloDao helloDao; @Before public void setUp() throws Exception { dbi = new DBI(dataSource); helloDao = dbi.onDemand(HelloDao.class); } @Test @DataSet("HelloDaoTest.testSet.xml") public void helloDao() throws Exception { Person p = helloDao.getPerson(); assertEquals("First", p.getFirstName()); } } 

And my fixture ( HelloDaoTest.testSet.xml )

 <?xml version="1.0" encoding="UTF-8" ?> <dataset> <person first_name="First" last_name="Last" /> </dataset> 

and pom.xml file:

 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.experiment.springboot</groupId> <artifactId>testspringbootproj</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Spring Boot Blank Project (from https://github.com/making/spring-boot-blank)</name> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.7.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <start-class>com.experiment.springboot.App</start-class> <java.version>1.8</java.version> <lombok.version>1.14.8</lombok.version> <log4jdbc.log4j2.version>1.16</log4jdbc.log4j2.version> <rest.assured.version>2.3.3</rest.assured.version> <jdbi.version>2.78</jdbi.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.jayway.restassured</groupId> <artifactId>rest-assured</artifactId> <version>${rest.assured.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>${log4jdbc.log4j2.version}</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4-1206-jdbc42</version> </dependency> <dependency> <groupId>org.jdbi</groupId> <artifactId>jdbi</artifactId> <version>${jdbi.version}</version> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-dbunit</artifactId> <version>3.4.6</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>${spring-loaded.version}</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>3.4.1</version> <configuration> <propertyFile>src/main/resources/liquibase.properties</propertyFile> </configuration> </plugin> </plugins> </build> </project> 

When I run this test, I get the following error:

 java.lang.NullPointerException at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:820) at org.unitils.database.transaction.impl.DefaultUnitilsTransactionManager.rollback(DefaultUnitilsTransactionManager.java:157) at org.unitils.database.DatabaseModule.rollbackTransaction(DatabaseModule.java:425) at org.unitils.database.DatabaseModule.endTransactionForTestMethod(DatabaseModule.java:390) at org.unitils.database.DatabaseModule$DatabaseTestListener.afterTestTearDown(DatabaseModule.java:486) at org.unitils.core.Unitils$UnitilsTestListener.afterTestTearDown(Unitils.java:315) at org.unitils.core.junit.AfterTestTearDownStatement.evaluate(AfterTestTearDownStatement.java:48) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.unitils.core.junit.BeforeTestClassStatement.evaluate(BeforeTestClassStatement.java:41) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 

It seems that the test code has not even been reached. What am I doing wrong?

+8
java spring junit postgresql unitils
source share
2 answers

You have two database implementations in your pom.xml without specifying areas. Spring cannot guess which one should be right, hence the exception.

  <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> [...] <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4-1206-jdbc42</version> </dependency> 

Most likely, this will help you: Configure a specific database database for testing purposes in Spring

+3
source share

I cannot add a comment due to <50 rep. I thought maybe that would be helpful.

Rollback transaction after @Test

It does not use Unitils, but it seems to be the behavior you are looking for. It seems that Unitils was last updated back in 2011 (and my suspicion is that your problem lies), so it’s worth the reluctance to spend it.

+2
source share

All Articles