Подтвердить что ты не робот

Откат транзакции после @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 для этого

4b9b3361

Ответ 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();
    }
}