2012-06-15 2 views
4

Вот мой тест:Как откатить тест

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:repositoryContextTest.xml" }) 
@Transactional 
@TransactionConfiguration(defaultRollback = true) 
public class SeasonITest { 
@Autowired 
private SeasonDao seasonDao; 

@Test 
public void createSeason() throws Exception { 
    Season season = new Season(); 
    season.setName("2012"); 
    seasonDao.createSeason(season); 
} 

и DataSource в моем файле конфигурации боба

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url" value="jdbc:mysql://localhost/tournament_system" /> 
    <property name="username" value="root" /> 
    <property name="password" value="root" /> 
    <property name="defaultAutoCommit" value="false"/> 
    <property name="poolPreparedStatements" value="false"/> 
    <property name="maxOpenPreparedStatements" value="0"/> 
</bean> 

<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 
<tx:annotation-driven transaction-manager="transactionManager" /> 

Когда я запускаю этот тест есть новая запись создается в моей базе данных.

Как я могу отменить эту транзакцию?

Это выход журнала я вижу:

2012-06-15 15:00:02,173 [main] INFO - ionalTestExecutionListener - 
Rolled back transaction after test execution for test context 
[[TestCo[email protected] testClass = SeasonITest, 
    locations = array<String>['classpath:repositoryContextTest.xml'], 
    testInstance = [email protected], 
    testMethod = [email protected], testException = [null]]] 

UPDATE:

все ответы ниже хотят изменить логику или ядро ​​базы данных, что я не хочу. Поэтому я предлагаю точку репутации для правильного ответа:

Почему, когда у меня есть это: @TransactionConfiguration(defaultRollback = true) в тестах конфигурации транзакций не откатываются назад и как я могу это исправить?

ответ

7

Если вы используете MySQL с движком MyISAM, попробуйте переключиться на InnoDB.

Для более сложного теста вам, вероятно, понадобится насмешливая инфраструктура или отдых в БД.

EDIT1: Согласно документации, InnoDB является транзакционным с полной поддержкой ACID, в то время как MyISAM поддерживает атомные операции. Больше чтение: Transaction and Atomic Operation Differences

EDIT2: В @TransactionConfiguration значение по умолчанию для defaultRollback верно, так что вместо того, чтобы комментировать линия вы должны добавить @TransactionConfiguration (defaultRollback = ложь)

+0

гм ТНХ много он работает и что это отличается от InnoDB и MyISAM? – hudi

+0

hm но после того, как я сменил двигатель. и комментировать defaultRollback = true, то эта запись не сохраняется в моем db – hudi

+0

@hudi сделал ли настройку defaultRollback для объяснения false? –

0

Там также другие решения для этого:

  1. Используйте насмешливые рамки (т.е. Mockito) издеваться источником данных. Таким образом, вы проверите только свою логику DAO.
  2. Используйте отдельную базу данных для тестирования, которая может быть настроена для каждого теста. Вы можете использовать DBUnit для этого.
  3. Используйте базу данных в памяти (т. Е. HSQL), чтобы изменения не сохранялись.

Таким образом, вам не придется откатывать ваши изменения.

0

Пожалуйста, убедитесь, что вы должны должны объявить :

<tx:annotation-driven transaction-manager="transactionManager" /> 

в вашем файле конфигурации пружины, например: (ApplicationContext.xml).

Как пояснил @Lieber, но больше объяснений: MySQL Server (версия 3.23-max и все версии 4.0 и выше) поддерживает транзакции с транзакционным хранилищем InnoDB. InnoDB обеспечивает полное соответствие требованиям ACID. См. Главу 14 «Двигатели хранения». Информацию о различиях InnoDB от стандартного SQL в отношении обработки ошибок транзакций см. В разделе 14.3.13 «Обработка ошибок InnoDB».

Другие нетранзакционные системы хранения данных на сервере MySQL (например, MyISAM) следуют другой парадигме целостности данных, называемой «атомарные операции». В транзакционных терминах таблицы MyISAM эффективно работают в режиме autocommit = 1. Атомные операции часто обеспечивают сопоставимую целостность и высокую производительность. Таким образом, механизм транзакционного хранилища MyISAM всегда выполняет транзакцию autocommit.

+0

yes У меня это в моем контексте – hudi

0

пытаются аннотирования метод испытания с @Transactional

+0

все еще без успеха :( – hudi

0

нафига было это то же самое случилось со мной, как 3 дня назад. Попробуйте добавить TransactionManager = "TransactionManager" к вашему @contextConfiguration:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:PersistenceHelper-context.xml"}) 
@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager") 
@Transactional 

Кроме того, я не на 100% процентов уверен в этом, но ваш файл XML должен соответствовать формату "* -context". Дайте мне знать, если вы хотите увидеть мой файл PersistenceHelper-context.xml.

0
  • Try простирающийся AbstractTransactionalJUnit4SpringContextTests
  • Обратите внимание, что MySql таблицы MyISAM не являются транзакционными, вы должны использовать таблицы типа INNODB (см here и here)
  • Ваш DAO также помеченный @Transactional? Это может вызвать проблему (см. here)
1

На первый взгляд, ваш код и конфигурация выглядят правильно. Однако не могли бы вы разместить свой объект SeasonsDAO. Сначала нам нужно убедиться, что SeasonsDAO правильно настроен для транзакций.

SeasonsDAO должен участвовать в одном и том же TransactionContext в качестве тестового примера, и нет способа проверить это с помощью кода, который вы опубликовали.

Вы отметили SeasonsDAO как @Transactional?

Если это не так, я не уверен, как TransactionProxyFactoryBean сможет проксировать и декларативно управлять транзакцией.

На высоком уровне пружина использует понятие проксирования для выполнения множества услуг, таких как управление транзакциями.

Если вы отметите что-то как @Transactional, Spring будет динамически создавать прокси-сервер, который будет реализовывать те же интерфейсы, что и ваш целевой класс. После того, как он проксирован, перехватчик транзакций будет переносить вызовы методов в ваш целевой класс и решать, откатываться или совершать транзакции, основываясь на стандартах или правилах, которые вы можете указать.

+0

Нет У меня есть знак Только для транзакции test – hudi

+0

Тогда я уверен, что ваш SeasonsDAO не работает в транзакции и поэтому не откатит вставку. –

+0

вопрос ответ и тест были анотированы как транзакционные, поэтому я думаю, что это достаточно – hudi

0

Попробуйте использовать следующий метод после логики теста.

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 
+0

этот исключение кода: org.springframework.transaction.NoTransactionException: транзакция с транзакцией без транзакций TransactionStatus в области – hudi

0

Ваш Dao должен быть отмечен @Transactional.

Также аннотировать тест с:

@TestExecutionListeners(TransactionalTestExecutionListener.class) //Rolls back transactions by default 
+0

Когда я добавляю ваши записи, я получил NPE в этой строке: seasonDao. createSeason (сезон); – hudi

Смежные вопросы