Тесты 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...
      }