首页 > 解决方案 > 在@DataJpaTest 中测试唯一约束

问题描述

我编写了这个测试来验证Domain.name数据库中的唯一约束。但它不起作用:我希望在domainRepository.saveAndFlush(domainDuplicate)操作上引发异常,但测试成功结束。

@RunWith(SpringRunner::class)
@DataJpaTest
class DomainRepositoryTest {

    @Autowired
    private lateinit var util: TestEntityManager
    @Autowired
    private lateinit var domainRepository: DomainRepository

    @Test
    fun testNonUniqueDomainSave() {
        // Arrange
        val domain = Domain(name = "name")
        util.persist(domain)
        util.flush()
        util.clear()

        val domainDuplicate = domain.copy(id = 0L)

        // Act
        domainRepository.saveAndFlush(domainDuplicate)
        // Exception is expected
    }
}

测试日志(缩短):

INFO 13522 --- [           main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@8f8717b testClass = DomainRepositoryTest,...]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@65f36591]; rollback [true]

Hibernate: insert into domains (name, id) values (?, ?)
Hibernate: insert into domains (name, id) values (?, ?)
Hibernate: insert into domains (name, id) values (?, ?)

INFO 13522 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test: [DefaultTestContext@8f8717b testClass = DomainRepositoryTest, ...], attributes = map[[empty]]]

问题:如何解决这个测试?附加问题:为什么在日志中有 3 个插入操作?

数据库:H2

标签: kotlinspring-data-jpaunique-constraintdatabase-testing

解决方案


这是测试中数据库初始化的问题:没有唯一约束!我认为 Liquibase 应该在任何测试之前运行迁移,但事实上,它没有被配置为这样做。默认情况下,Hibernate DDL 自动更新用于在测试中创建数据库模式。

我可以想到两种可能的解决方案:

  1. 添加 liquibase-core jar 以测试类路径并将其配置为运行迁移
  2. 在域实体上声明@UniqueConstraint并依赖 Hibernate DDL。

推荐阅读