Тесты JUnit всегда откатывают транзакции
Я запускаю простой тест JUnit против приложения DAO. Проблема в том, что я всегда получаю:
javax.persistence.RollbackException: Transaction marked as rollbackOnly
Тест JUnit:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
public class PerformanceTest {
@Test
@Transactional(propagation= Propagation.REQUIRES_NEW)
@Rollback(false)
public void testMsisdnCreationPerformance() {
// Create a JPA entity
// Persist JPA entity
}
}
Как вы можете видеть, я четко заявляю, что не нужно откатывать этот метод.
Всегда ли поддержка Spring JUnit устанавливает откат на true?
Ответы
Ответ 1
Он должен работать, как вы ожидаете, но может быть, вы открываете другую транзакцию в тестируемом классе или у вас есть другая функция/или ошибка где-то.
Btw эти аннотации должны быть enougth:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@Transactional
public class PerformanceTest {
@Test
@Rollback(false)
public void testMsisdnCreationPerformance() {
// Create a JPA entity
// Persist JPA entity
}
}
@See Spring Ссылка Глава 9.3.5.4 Управление транзакциями
Ответ 2
Странно желать теста, который изменяет вашу базу данных и сохраняет изменения.
Тесты должны быть ортогональны: ни один тест не зависит от другого.
Кроме того, тесты должны быть независимы от порядка испытаний и даже idempotent.
Итак, либо вы хотите изменить свою базу данных в своем методе setUp()
, либо отменить изменение вашего метода tearDown()
, либо вы хотите настроить тестовую базу данных с некоторыми хорошими значениями в ней для тестов.
Возможно, я что-то пропустил, но обычно вам этого не нужно.
Ответ 3
Просто добавьте аннотацию Откат и установите флаг в false.
@Test
@Rollback(false)
Ответ 4
От официальной документации:
По умолчанию тестовые транзакции будут автоматически откатываться после завершение теста; однако транзакционная фиксация и откат поведение можно настроить декларативно через @Commit и @Rollback Аннотации
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#integration-testing-annotations
@Commit указывает, что транзакция для метода транзакционных испытаний должны быть зафиксированы после завершения метода тестирования. @Commit может использоваться как прямая замена для @Rollback (false), чтобы больше явно передают намерение кода.
Ответ 5
Я согласен с ответом Ральфа.
Propagation.REQUIRES_NEW создает новую транзакцию, и это, вероятно, не соответствует основному транзакционному маршруту, в котором выполняется тестирование.
В моем простом опыте аннотация @Transactional будет правильно работать, чтобы определить транзакционный контекст, в котором должен выполняться каждый отдельный тест, делегируя этому конкретному текущему предложению Rollback (как показано Ralph).
Ответ Ральфа полезен, и в то же время ответ Snicolas касается конкретного случая управления контекстом тестов.
idempotence является фундаментальным для интеграции и автоматических тестов, но должен быть разными способами их реализации.
Вопрос в том, какие методы у вас есть? И какое поведение имеют эти методы?
[...]
@Transactional
public class Test {
@Test
@Rollback(false)
public void test() {
[...]
Является простым, вопросительно-последовательным способом:)
Ответ 6
I use Junit5, both commit and rollback(false) works with me.
@ExtendWith(SpringExtension.class)
@SpringBootTest
@Transactional
public class MyIntegrationTest {
@Test
@DisplayName("Spring Boot Will Rollback Data, " +
"Can Disable it By Add @Commit Or @Rollback(false) Annotation")
//@Commit
//@Rollback(false)
public void test() throws Exception {
//your test codes here...
}