首页 > 解决方案 > @Transactional 不会回滚 DAO @Test 方法

问题描述

我创建了一个MySQL 数据库并填充了用于测试的行。我想在这个数据库上做我的 DAO 单元测试。每次测试后都会进行回滚@Test@Transactional不幸的是,它不起作用,因为我的数据库仍在进行更改。

我正在使用以下 context.xml加载我的Spring配置

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

这个stackoverflow问题说我

必须PlatformTransactionManager在应用程序上下文中提供一个 bean

但即使有了它(它transactionManager在我的上下文中)什么也没有发生,我的数据库仍然被修改而不是回滚。

这是我的 DAO 测试课

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

我是否在我的配置或我对如何/应该如何工作/做什么的理解@Transactional中遗漏了什么?

标签: javamysqlspring

解决方案


正如@M.Deinum 在评论部分发布的那样,

@Transactionalon tests 仅适用于SpringRunner作为单元测试运行器。

如果您自己创建应用程序上下文,则它不起作用。

也不要忘记将事务模式添加到context.xml能够正确加载您的上下文文件中。

DAO 测试类

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

上下文.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>

推荐阅读