Так что у меня есть интересная проблема, с которой мне понадобится помощь.Я знаю, что было задано множество вопросов об откате транзакций с использованием junit, но я считаю, что моя проблема немного отличается.Чтобы лучше понять проблему, позвольте мне начать с самого начала.
Я внедрил UserManagementService с соответствующими DAO для системы управления пользователями.Существует общий метод CreateUser (User obj), который используется для создания уникального пользователя.Теперь существует ограничение на то, что адреса электронной почты уникальны, поэтому, если мы попытаемся вызвать этот метод с адресом электронной почты, который уже был использован, мы выдадим пользовательское исключение UserManagementException с соответствующим сообщением об ошибке.Все это прекрасно работает, однако, проблема, с которой я сталкиваюсь, заключается в тестировании модулей.О, прежде чем я забуду, позвольте мне упомянуть программный стек, который я использую [ Java, Spring, Hibernate ]
У меня есть свой класс модульного теста с аннотациями Transactional для каждого метода, который на самом делепопадает в БД.Эти методы также имеют аннотацию @Rollback, так что все вставки, обновления и удаления откатываются в конце каждого вызова теста.Итак, проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы протестировать сценарий с уникальным ограничением пользователя.Вызывая createUser (obj) второй раз с объектом пользователя с тем же адресом электронной почты, я хочу убедиться, что выдается исключение UserManagementException.Однако, поскольку он является транзакционным, всякий раз, когда выдается исключение, транзакция выполняет откат до завершения модульного теста и, следовательно, не проходит тест.Ниже приведен тестовый пример.
@Test
@Rollback
@Transactional
public void testUniqueCreateConsoleUser() {
boolean success;
ConsoleUser newUser;
//first one
userManagementDao.createConsoleUser(user);
//second one. This shd throw a UserManagementException
try {
//now try and insert a new user with same email
newUser = new ConsoleUser("Queen", "Kong", "king.kong@blah.com", "kingkong","Universal Studios", "America/Los_Angeles", false, null);
userManagementDao.createConsoleUser(newUser);
//if this passed this is a problem. Console users should have unique email address
success = false;
} catch (UserManagementException e) {
success = true;
}
Assert.assertTrue(success);
}
Странно то, что когда я запускаю его через отладчик, метод Assert.assertTrue () вызывается корректно, но в конечном итоге тест завершается неудачей.
Еще я попробовал добавить опору в аннотацию @Transactional.Я добавил текущую @ Transactional (noRollbackFor = UserManagementException.class) в надежде, что, если возникнет исключение, откат не будет вызван тогда, но в конце теста.Возможно, я подхожу к этому неверно, поэтому любые идеи или лучшие практики, касающиеся такого рода тестирования, будут высоко оценены.
Примечание. Ниже приведен фрагмент трассировки стека.
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:695)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$afterReturning$org_springframework_transaction_aspectj_AbstractTransactionAspect