Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在每个单元测试之后回滚_Java_Mysql_Spring_Unit Testing_Spring Test - Fatal编程技术网

Java 在每个单元测试之后回滚

Java 在每个单元测试之后回滚,java,mysql,spring,unit-testing,spring-test,Java,Mysql,Spring,Unit Testing,Spring Test,我使用Spring、Hibernate和MySQL开发应用程序。我为我的一个表创建了DAO。现在,我想测试DAO的方法(保存、查找等)。问题是这些方法会影响数据库数据,所以我希望在执行特定方法后回滚所有更改。我在@TransactionConfiguration中设置了defaultRollback=true,试图做到这一点,但它不起作用。下面我将粘贴最重要的代码片段。有人知道如何在每个方法之后强制回滚吗 我在MySQL中的表使用InnoDB引擎。 事实上,测试执行后控制台包含以下信息: INF

我使用Spring、Hibernate和MySQL开发应用程序。我为我的一个表创建了DAO。现在,我想测试DAO的方法(保存、查找等)。问题是这些方法会影响数据库数据,所以我希望在执行特定方法后回滚所有更改。我在
@TransactionConfiguration
中设置了
defaultRollback=true
,试图做到这一点,但它不起作用。下面我将粘贴最重要的代码片段。有人知道如何在每个方法之后强制回滚吗

我在MySQL中的表使用InnoDB引擎。 事实上,测试执行后控制台包含以下信息:
INFO:test context的测试执行后回滚事务…
但提交了数据库中的更改

UsersDAOTest

@ContextConfiguration(locations={"classpath:applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
@Transactional
public class UsersDAOTest {

    @Autowired
    UsersHibernateDAO usersDAO;

    @Test
    public void test1() {
        List<Users> results = usersDAO.findAll();
        Assert.assertEquals(0, results.size());
    }

    @Test
    public void test2() {
        Users user = new Users("mchrobok", "12345678901234567890123456789012");
        usersDAO.saveOrUpdate(user);
        List<Users> results = usersDAO.findAll();
        Assert.assertEquals(1, results.size());     
    }   
}    
@ContextConfiguration(位置={“类路径:applicationContext.xml”})
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager=“transactionManager”,defaultRollback=true)
@交易的
公共类usersDataTest{
@自动连线
usershibernatedaousersdao;
@试验
公共void test1(){
List results=usersDAO.findAll();
Assert.assertEquals(0,results.size());
}
@试验
公共无效测试2(){
用户用户=新用户(“mchrobok”、“1234567890121345678901234567890123456789012”);
usersDAO.saveOrUpdate(用户);
List results=usersDAO.findAll();
Assert.assertEquals(1,results.size());
}   
}    
Hibernate(Hibernate.cfg.xml)


org.hibernate.dialogue.mysqldialogue
符合事实的
创建下降
Spring配置(applicationContext.xml)


hibernate.cfg.xml
编辑

UsersDAO(它是通用的,但并不重要)

公共类genericBernateDao实现GenericDAO{
私人会话工厂会话工厂;
私有类和私有类;
公共genericibernatedao(){
ParameteredType类型=((ParameteredType)getClass().getGenericSuperclass());
persistClass=((类)type.getActualTypeArguments()[0]);
}
public void setSessionFactory(SessionFactory SessionFactory){
this.sessionFactory=sessionFactory;
}
@凌驾
公共列表findAll(){
Criteria=sessionFactory.openSession().createCriteria(persistClass);
返回条件。list();
}
@凌驾
公共作废保存或更新(T实体){
sessionFactory.openSession().saveOrUpdate(实体);
}
}

如果要在hibernate代码中打开一个新会话,则应改用getCurrentSession()

代码中的问题是DAO类试图自己管理事务。在现代Spring应用程序中,事务管理应该在服务层中执行


因此,这意味着您的服务方法通常应该用
@Transactional

注释。如果您要在hibernate代码中打开一个新会话,则应该使用getCurrentSession()

代码中的问题是DAO类试图自己管理事务。在现代Spring应用程序中,事务管理应该在服务层中执行


因此,这意味着通常您的服务方法应该用
@Transactional

注释,这显然是一种错误的测试方法。您不应该在生产环境中测试更改,然后将其回滚,而应该使用开发、测试等较低级别的环境。对于数据库和所有其他系统层,该数据库是我的测试环境。但我的问题不同。如果在每个方法之后提交更改,它会影响其他方法(正如我所知,顺序执行是随机的)。这就是我想在每个方法之后回滚的原因。如果是您的测试环境,为什么要回滚它?如果要恢复到初始状态,在运行测试之前拍摄快照,然后在完成测试后重新应用快照不是更简单吗?defaultRollback默认为trueanyway@foampile我在乎,因为执行的顺序是随机的。Test1()读取所有用户,结果应为0。但是,如果test2()在test1()之前运行,那么test1()将失败,因为所有更改都已提交。这显然是一种错误的测试方式。您不应该在生产环境中测试更改,然后将其回滚,而应该使用开发、测试等较低级别的环境。对于数据库和所有其他系统层,该数据库是我的测试环境。但我的问题不同。如果在每个方法之后提交更改,它会影响其他方法(正如我所知,顺序执行是随机的)。这就是我想在每个方法之后回滚的原因。如果是您的测试环境,为什么要回滚它?如果要恢复到初始状态,在运行测试之前拍摄快照,然后在完成测试后重新应用快照不是更简单吗?defaultRollback默认为trueanyway@foampile我在乎,因为执行的顺序是随机的。Test1()读取所有用户,结果应为0。但如果test2()将在test1()之前运行,那么test1()将失败,因为所有更改都已提交。
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>    
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">create-drop</property>

        <mapping class="pl.fp.microblog.domain.Users"/>
    </session-factory>
</hibernate-configuration>
<beans>
     <context:component-scan base-package="pl.fp.microblog" />
     <tx:annotation-driven />

     <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"    destroy-method="close">
         <beans:property name="driverClassName" value="com.mysql.jdbc.Driver"/>
         <beans:property name="url" value="jdbc:mysql://localhost:3306/Microblog"/>
         <beans:property name="username" value="root"/>
         <beans:property name="password" value="root"/>
     </beans:bean>

     <beans:bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
     <beans:property name="dataSource" ref="dataSource" />
         <beans:property name="configLocation">
             <beans:value>
                 hibernate.cfg.xml
         </beans:value>
         </beans:property>
     </beans:bean>

     <beans:bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <beans:property name="sessionFactory" ref="sessionFactory" />
     </beans:bean>

     <beans:bean name="usersDAO" class="pl.fp.microblog.dao.UsersHibernateDAO">
         <beans:property name="sessionFactory" ref="sessionFactory" />
     </beans:bean>
</beans:beans>
public class GenericHibernateDAO<T> implements GenericDAO<T> {
    private SessionFactory sessionFactory;
    private Class<?> persistClass;

    public GenericHibernateDAO() {
        ParameterizedType type = ((ParameterizedType)getClass().getGenericSuperclass());
        persistClass = ((Class<?>) type.getActualTypeArguments()[0]);
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public List<T> findAll() {
        Criteria criteria = sessionFactory.openSession().createCriteria(persistClass);
        return criteria.list();
    }

    @Override
    public void saveOrUpdate(T entity) {
        sessionFactory.openSession().saveOrUpdate(entity);
    }
}