@Transactional doesn't rollback on DAO @Test methods

VictorGalisson :

I have a MySQL database created and filled with test-purpose rows. I want to do my DAO unit tests on this database. Each @Test is @Transactional so a rollback is done after each test. Unfortunately, it is not working as changes are still made to my database.

I'm loading my Spring configuration with the following context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:jdbc="http://www.springframework.org/schema/jdbc"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                                                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                                    http://www.springframework.org/schema/jdbc
                                                    http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"
            xmlns:tx="http://www.springframework.org/schema/tx">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
        <property name="url" value="jdbc:mysql://localhost:3306/push_test" />  
        <property name="username" value="push_dao" />  
        <property name="password" value="pushpassword" />
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource"  ref="dataSource" />    
    </bean>

    <bean id="userPushDAO" class="my.package.userPushDAOImpl">
         <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

This stackoverflow issue said that I

must provide a PlatformTransactionManager bean in the application context

But even with it (it's the transactionManager in my context) nothing happens, my database is still modified and not rollbacked.

Here is my DAO test class

public class UtilisateurPushDAOImplTest {

    private static ApplicationContext ctx;

    private static UserPushDAO userPushDAO;


    @BeforeClass
    public static void doSetup() {
        ctx = new ClassPathXmlApplicationContext("context.xml");
        userPushDAO = (userPushDAO) ctx.getBean("userPushDAO");
    }

    @Test
    @Transactional
    public void test() {
         userPushDAO.deleteById("id");
    }
}

Am I missing something in my configuration or in my comprehension on how/what @Transactional should work/do ?

VictorGalisson :

As @M.Deinum posted in the comment section,

@Transactional on tests will only work with the SpringRunner as a Unit test runner.

It doesn't work if you create the application context yourself.

Also don't forget to add the transaction schema into the context.xml to be able to load your context file correctly.

DAO test class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/context.xml"})
public class UserPushDAOImplTest {

    @Resource(name="userPushDAO")
    private UserPushDAO userPushDAO;

    @Test
    @Transactional
    public void test() {
         userPushDAO.deleteById("id");
    }
}

context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:jdbc="http://www.springframework.org/schema/jdbc"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                                http://www.springframework.org/schema/beans/spring-beans.xsd
                                http://www.springframework.org/schema/jdbc
                                http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
                                http://www.springframework.org/schema/context
                                http://www.springframework.org/schema/context/spring-context.xsd">  

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
        <property name="url" value="jdbc:mysql://localhost:3306/push_test" />  
        <property name="username" value="push_dao" />  
        <property name="password" value="pushpassword" />
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"  ref="dataSource" />    
    </bean>

    <bean id="userPushDAO" class="my.package.userPushDAOImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=108207&siteId=1