9

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 entities + mapper:

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'm using junit and unitils to write a unit test for this Dao. I have the unitils.properties file set up like so:

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 my 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 the 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.ParentRunner3ドル.run(ParentRunner.java:290)
 at org.junit.runners.ParentRunner1ドル.schedule(ParentRunner.java:71)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
 at org.junit.runners.ParentRunner.access000ドル(ParentRunner.java:58)
 at org.junit.runners.ParentRunner2ドル.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 looks like the test code is not even reached. What am I doing wrong?

asked May 14, 2017 at 21:14
4
  • Not an expert on any of these techs, but if you look at the stack trace it looks as if the tests expect there to be some kind of transaction manager in a complete spring context, but that doesn't get set up (no spring junit runner). Commented May 17, 2017 at 6:13
  • please look at the second line of the test @RunWith(UnitilsBlockJUnit4ClassRunner.class) Commented May 17, 2017 at 6:16
  • 1
    Well, did you set up a Spring Application Context as described in unitils.sourceforge.net/tutorial-spring.html ? Commented May 17, 2017 at 6:19
  • yes i did this @TassosBassoukos Commented May 22, 2017 at 5:01

2 Answers 2

3
+50

You do have two database implementations in your pom.xml, without specifying scopes. Spring is not able to guess which one shall be the right one, hence an 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 further: Configure specific in memory database for testing purpose in Spring

answered May 23, 2017 at 13:39
Sign up to request clarification or add additional context in comments.

Comments

2

I can't add a comment because of <50 rep. I thought maybe this would be useful.

Rollback transaction after @Test

It isn't using Unitils, but does seem to be the behavior that you are looking for. Unitils seems to have been last updated back in 2011 (and my suspicion is that is where your problem lies) so it might be worth junking it.

answered May 23, 2017 at 11:07

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.