Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rollback test

Tags:

java

spring

Here's my test:

@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);
}

and the dataSource in my bean configuration file

<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" />

When I run this test there a new record is created in my database.

How can I rollback this transaction?

This is the log output I see:

2012-06-15 15:00:02,173 [main] INFO  - ionalTestExecutionListener - 
 Rolled back transaction after test execution for test context 
 [[TestContext@76db09 testClass = SeasonITest, 
   locations = array<String>['classpath:repositoryContextTest.xml'], 
   testInstance = org.toursys.repository.dao.SeasonITest@1265109, 
   testMethod = createSeason@SeasonITest, testException = [null]]]

UPDATE:

all answers below want to change logic or database engine what I dont want. So I am offering reputation point to the right answer:

Why when I have this: @TransactionConfiguration(defaultRollback = true) in transaction configuration tests are not rolled back and how I can fix it ?

like image 276
hudi Avatar asked Jun 15 '12 13:06

hudi


2 Answers

If you are using MySQL with MyISAM engine try switching to InnoDB.

For more complicated test you will probably need a mocking framework or DB recreation.

EDIT1: According to the documentation InnoDB is transactional with full ACID support while MyISAM has support for atomic operations. More reading: Transaction and Atomic Operation Differences

EDIT2: In @TransactionConfiguration the default value for defaultRollback is true, so instead of commenting the line you should add @TransactionConfiguration(defaultRollback=false)

like image 109
Krystian Lieber Avatar answered Oct 23 '22 12:10

Krystian Lieber


On the surface, your code and configuration looks correct. However, could you please post your SeasonsDAO object. We would first need to verify that the SeasonsDAO is correctly configured for transactions.

SeasonsDAO needs to be participating in the same TransactionContext as your test case and there is no way to verify that with the code you posted.

Did you mark SeasonsDAO as @Transactional ?

If it is not, I am not sure how the TransactionProxyFactoryBean would be able to proxy and declaratively manage the transaction.

At a high level, spring uses the notion of proxying to perform many services such as transaction management.

If you mark something as @Transactional, Spring will dynamically create a proxy that will implement the same interfaces as your target class. Once it is proxied, a transaction interceptor will wrap method calls to your target class and decide whether to rollback or commit based on defaults or rules that you may specify.

like image 26
Roy Kachouh Avatar answered Oct 23 '22 11:10

Roy Kachouh