Spring и JUnit, разница в аннотировании классов и методов с помощью @Transaction?


Я хотел бы понять, что если я аннотирую свой класс junit с помощью @Transactional, Spring создаст только одну транзакцию, которая будет разделена между моими методами @Test и откатится в конце. В то время как если вместо этого я отмечу каждый отдельный @ Test с помощью @Transactional, новая транзакция будет создана и откатана на основе @Test. Я не совсем нашел ожидаемое поведение в официальной документации (Ссылка ).

2 3

2 ответа:

Размещение @Transactional на уровне класса эквивалентно размещению его на каждом из методов тестирования.

Я не думаю, что существует простой способ достижения вашего первого сценария, то есть одной транзакции для всех тестов. Я не уверен, что это имело бы большой смысл в любом случае, так как тесты будут выполняться в случайном порядке, поэтому вы не можете полагаться на видимые модификации друг друга. Конечно, вы всегда можете явным образом вызвать свои методы из одного uber-теста с одной транзакцией.

@Transactional на уровне класса тестового случая JUnit будет запускаться новая транзакция перед каждым методом тестирования и откатываться после него.

Вы не можете легко запустить новую транзакцию в начале тестового класса и держать ее открытой для всего класса, по крайней мере Spring не поддерживает это. Ваш первый обходной путь будет использовать @BeforeClass/@AfterClass пара, но они должны быть static таким образом, у вас нет доступа к менеджеру транзакций. Но сначала задайте себе вопрос, почему вы хотите это сделать? Звуки как один тест зависит от выходных данных или побочных эффектов базы данных другого. Это большой анти-паттерн в тестировании, не говоря уже о том, что JUnit не гарантирует порядок, в котором выполняются методы тестирования. Может быть, вам просто нужно настроить базу данных перед каждым тестовым случаем? @Before и @After выполняются в контексте транзакции Spring, поэтому вы можете использовать их там.