Прежде всего, я нашел много обсуждений на 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
initTest
Ответы:
Просто добавьте
@Transactional
аннотацию поверх теста:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"testContext.xml"}) @Transactional public class StudentSystemTest {
По умолчанию Spring начнет новую транзакцию, связанную с вашим тестовым методом и
@Before
/@After
обратными вызовами, откатываясь в конце. Он работает по умолчанию, достаточно иметь в контексте какой-нибудь менеджер транзакций.От: 10.3.5.4 Управление транзакциями (выделено жирным шрифтом):
источник
PlatformTransactionManager
. Иначе как Spring узнает о ваших транзакциях и базе данных?@Transactional
на@Test
уровне метода, а не на уровне класса.В сторону : попытка изменить ответ Томаша Нуркевича была отклонена:
Правильная и постоянная ссылка на соответствующий раздел документации по интеграционному тестированию.
источник
Ответы, в которых упоминается добавление
@Transactional
, верны, но для простоты вы можете просто иметь свой тестовый классextends AbstractTransactionalJUnit4SpringContextTests
.источник
Я знаю, я слишком поздно, чтобы публиковать ответ, но надеюсь, что это может кому-то помочь. Кроме того, я только что решил эту проблему с моими тестами. Вот что у меня было в тесте:
Мой тестовый класс
@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" />
Надеюсь, поможет.
источник
Вам нужно запустить свой тест с контекстом Spring и менеджером транзакций, например,
@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 } }
См. Главу
3.5.8. Transaction Management
справочника Spring для получения дополнительной информации.источник
В дополнение к добавлению
@Transactional
по@Test
методу, вам также необходимо добавить@Rollback(false)
источник
Вы можете отключить откат:
@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(); } }
источник