Тесты JUnit всегда откатывают транзакции - PullRequest
24 голосов
/ 22 марта 2012

Я запускаю простой тест 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?

Заранее спасибо,

Ответы [ 6 ]

49 голосов
/ 22 марта 2012

Это должно работать, как вы ожидаете, но, возможно, вы открываете другую транзакцию в тестируемом классе или у вас есть другая функция / или ошибка где-то.

Кстати, аннотации должны быть достаточно:

@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
    }
}

@ См. Ссылка на пружину Глава 9.3.5.4 Управление транзакциями

11 голосов
/ 22 марта 2012

Странно хотеть тест, который изменит вашу базу данных и сохранит модификацию.Тесты должны быть ортогональными: ни один тест не зависит от другого.Более того, тесты должны быть независимы от порядка тестирования и даже идемпотента .

Так что вы либо хотите изменить базу данных в вашем методе setUp() и откатить изменение в вашем tearDown(), либо вы хотите настроить тестовую базу данных с некоторыми хорошими значениями для тестов.

Может быть, я что-то здесь упускаю, но обычно вам этого не нужно.

10 голосов
/ 04 декабря 2014

Просто добавьте аннотацию Rollback и установите флаг в значение false.

   @Test
   @Rollback(false)
3 голосов
/ 14 августа 2017

Из официальной документации:

По умолчанию тестовые транзакции будут автоматически откатываться после завершения теста;однако поведение фиксации транзакции и отката может быть настроено декларативно с помощью аннотаций @Commit и @Rollback

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#integration-testing-annotations

@ Commit означает, что транзакция для транзакционного тестаМетод должен быть зафиксирован после завершения метода тестирования.@Commit может использоваться в качестве прямой замены @Rollback (false) для более явного выражения цели кода.

0 голосов
/ 20 января 2019
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...
      }
0 голосов
/ 26 августа 2014

Я согласен с ответом Ральфа.

Propagation.REQUIRES_NEW создает новую транзакцию, и это, вероятно, не соответствует основному транзакционному маршруту, на котором выполняется тест.

В моем простом опыте аннотация @ Transactional будет правильно работать для определения транзакционного контекста, в котором должен выполняться каждый отдельный тест, делегируя этому конкретное текущее предложение Rollback (как показано Ральфом).

Ответ Ральфа полезен, и в то же время ответ Сниколаса касается конкретного случая управления контекстом тестов.Идемпотентность является фундаментальной для интеграции и автоматических тестов, но должны быть разными способами их реализации.Вопрос в том, какие у вас есть методы?И какое поведение имеют эти методы?

   [...]
   @Transactional

   public class Test {

   @Test
   @Rollback(false)
   public void test() {

   [...]

Это простой, согласованный с вопросом способ:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...