I wrote this test to verify unique constraint on Domain.name
in the database. But it doesn't work: I expect an exception to be thrown on the domainRepository.saveAndFlush(domainDuplicate)
operation, but the test ends successfully.
@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
}
}
Test log (shortened):
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]]]
Question: How to fix this test? Additional question: Why 3 insert operations in log?
Database: H2
It was a problem with database initialization in tests: there was no unique constraint! I assumed that Liquibase should run migrations before any tests but in fact, it was not configured to do so. By default, Hibernate DDL auto update is used to create DB schema in tests.
I can think of 2 possible solutions:
@UniqueConstraint
on domain entity and rely on Hibernate DDL.