Тестирование уникального ограничения в @DataJpaTest - PullRequest
1 голос
/ 05 мая 2019

Я написал этот тест для проверки уникального ограничения на 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

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

Это была проблема с инициализацией базы данных в тестах: не было уникального ограничения!Я предполагал, что Liquibase должен выполнить миграцию перед любыми тестами, но на самом деле он не был настроен для этого.По умолчанию автоматическое обновление Hibernate DDL используется для создания схемы БД в тестах.

Я могу подумать о 2 возможных решениях:

  1. добавить jar с жидким основанием для проверки пути к классам и настроить егодля выполнения миграций
  2. объявляйте @UniqueConstraint на доменном объекте и полагайтесь на Hibernate DDL.
0 голосов
/ 05 мая 2019

Причина в том, что saveAndFlash() выполняет обновление сущности, если она существует (Да, название метода сбивает с толку ..)

Если вы хотите проверить свой случай, вам нужнопереопределите saveAndFlash() и используйте EntityManager, используя метод persist.Вот пример переопределения save() метода Spring JPA:

@PersistenceContext
private EntityManager em;

@Override
@Transactional
public Domain save(Domain domain) {

    if (domain.getId() == null) {
       em.persist(domain);
       return domain;
    } else {
      return em.merge(domain);
    }
}
...