Откат транзакции после @Test
Прежде всего, я нашел много потоков в StackOverflow об этом, но ни один из них не помог мне, поэтому извините, чтобы спросить, возможно, дублировать вопрос.
Я запускаю тесты JUnit с помощью spring -test, мой код выглядит как
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {})
public class StudentSystemTest {
@Autowired
private StudentSystem studentSystem;
@Before
public void initTest() {
// set up the database, create basic structure for testing
}
@Test
public void test1() {
}
...
}
Моя проблема в том, что я хочу, чтобы мои тесты НЕ влияли на другие тесты.
Поэтому я хотел бы создать что-то вроде отката для каждого теста.
Я много искал для этого, но пока ничего не нашел.
Я использую Hibernate и MySql для этого
Ответы
Ответ 1
Просто добавьте аннотацию @Transactional
поверх теста:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"testContext.xml"})
@Transactional
public class StudentSystemTest {
По умолчанию Spring запустит новую транзакцию, связанную с вашим тестовым методом, и обратные вызовы @Before
/@After
, откат в конце. Он работает по умолчанию, он достаточно, чтобы иметь некоторый менеджер транзакций в контексте.
От: 10.3.5.4 Управление транзакциями (смелый рудник):
В платформе TestContext транзакции управляются TransactionalTestExecutionListener. Обратите внимание, что TransactionalTestExecutionListener
настроен по умолчанию, даже если вы явно не объявляете @TestExecutionListeners
в своем тестовом классе. Однако для поддержки транзакций вы должны предоставить PlatformTransactionManager
bean в контексте приложения, загружаемом семантикой @ContextConfiguration
. Кроме того, вы должны объявить @Transactional
на уровне класса или метода для своих тестов.
Ответ 2
Кроме того: попытка внести поправки в ответ Томаша Нуркевича была отклонена:
Это редактирование не делает сообщение даже немного более легким для чтения, проще найти, более точным или более доступным. Изменения либо полностью излишни, либо активно ухудшают читаемость.
Правильная и постоянная ссылка в соответствующий раздел документации по тестированию интеграции.
Чтобы включить поддержку транзакций, вы должны настроить PlatformTransactionManager
bean в ApplicationContext
, который загружается семантикой @ContextConfiguration
.
@Configuration
@PropertySource("application.properties")
public class Persistence {
@Autowired
Environment env;
@Bean
DataSource dataSource() {
return new DriverManagerDataSource(
env.getProperty("datasource.url"),
env.getProperty("datasource.user"),
env.getProperty("datasource.password")
);
}
@Bean
PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
Кроме того, вы должны объявить аннотацию Spring s @Transactional
либо на уровне класса или метода для своих тестов.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Persistence.class, SomeRepository.class})
@Transactional
public class SomeRepositoryTest { ... }
Аннотирование метода тестирования с помощью @Transactional
заставляет тест запускаться в транзакции, которая по умолчанию будет автоматически откатываться после завершения теста. Если тестовый класс аннотируется с помощью @Transactional
, каждый тестовый метод внутри этой иерархии классов будет выполняться внутри транзакции.
Ответ 3
Ответы на добавление @Transactional
верны, но для простоты вы можете просто получить свой тестовый класс extends AbstractTransactionalJUnit4SpringContextTests
.
Ответ 4
Я знаю, я опаздываю, чтобы опубликовать ответ, но надеюсь, что это может помочь кому-то. Плюс, я просто решил эту проблему, которую я имел с моими испытаниями. Это то, что я имел в своем тесте:
Мой тестовый класс
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "path-to-context" })
@Transactional
public class MyIntegrationTest
Контекст xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
У меня все еще была проблема, что база данных не была очищена автоматически.
Проблема была решена, когда я добавил следующее свойство в BasicDataSource
<property name="defaultAutoCommit" value="false" />
Надеюсь, что это поможет.
Ответ 5
Вам нужно запустить свой тест с помощью контекста спринта и менеджера транзакций, например
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/your-applicationContext.xml"})
@TransactionConfiguration(transactionManager="txMgr")
public class StudentSystemTest {
@Test
public void testTransactionalService() {
// test transactional service
}
@Test
@Transactional
public void testNonTransactionalService() {
// test non-transactional service
}
}
Подробнее см. главу 10. Testing
справочника Spring.
Ответ 6
Вы можете отключить Откат:
@TransactionConfiguration(defaultRollback = false)
Пример:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@Transactional
@TransactionConfiguration(defaultRollback = false)
public class Test {
@PersistenceContext
private EntityManager em;
@org.junit.Test
public void menge() {
PersistentObject object = new PersistentObject();
em.persist(object);
em.flush();
}
}