简体   繁体   English

使用Unitils针对Postgres数据库运行单元测试时发生NullPointerException

[英]NullPointerException while running unit test against 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: 以及以下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. 我正在使用junit和unitils编写此Dao的单元测试。 I have the unitils.properties file set up like so: 我已经设置了unitils.properties文件,如下所示:

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: 为了清楚起见,这是我的application.properties文件:

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 ) 还有我的装置( HelloDaoTest.testSet.xml

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

and the pom.xml file: 和pom.xml文件:

<?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 looks like the test code is not even reached. 看起来甚至没有达到测试代码。 What am I doing wrong? 我究竟做错了什么?

You do have two database implementations in your pom.xml, without specifying scopes. 在pom.xml中,确实有两个数据库实现,而没有指定范围。 Spring is not able to guess which one shall be the right one, hence an exception. Spring无法猜测哪一个是正确的,因此是一个例外。

    <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 这很可能会帮助您进一步: 在Spring中为测试目的在内存数据库中配置特定的

I can't add a comment because of <50 rep. 由于<50个代表,我无法添加评论。 I thought maybe this would be useful. 我认为这可能会有用。

Rollback transaction after @Test @Test之后的回滚事务

It isn't using Unitils, but does seem to be the behavior that you are looking for. 它没有使用Unitils,但似乎确实是您要寻找的行为。 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. Unitils似乎最近一次更新是在2011年(我怀疑这是您的问题所在),因此可能值得一试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM