单元测试,如何使spring管理服务不污染数据库

时间:2017-06-02 10:10:54

标签: java spring junit spring-transactions

我试图使用 spring和junit 测试DAO方法,我看到互联网上的一些做法是使用spring语句式事务管理(@Transactional)业务运营部表示,测试完成后,弹簧会让测试方法回滚,从而达到测试的目的。

然后我按照这种方法添加dao测试方法的操作,发现事务提交,回滚不成功,数据库我出来了测试数据。起初我以为是春天没有回滚,但在观察台后面打印信息发现有回滚信息,但为什么会失败,不知道。我发现了一些相关的程序,但我发现这并没有解决我的问题。非常困扰,希望得到你的帮助!

以下是我的代码和文件配置

  • DAOImpl的addUser()方法

    @Override
    public void addUser(User u) {
        Session session = sessionFactory.openSession();
        Transaction tc = session.getTransaction();
        try {
            tc.begin();
            session.save(u);
            tc.commit();
        }catch(Exception e){
            tc.rollback();
            e.printStackTrace();
        }
        return ;
    }
    
  • Daos.xml文件配置

    <bean id="txManager"
    
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="txManager" />
    

测试课

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/services.xml"})
@Transactional(transactionManager = "txManager")
@Rollback(true)
 public class UserServiceImplTest {
    @Autowired
    UserDAO userDAO; 

    @Test
    public void testAddUse(){
        User u = new User();
        u.setLevel(3);
        u.setName("ab11");
        u.setPassword("hh");
        userDAO.addUser(u);
        Assert.assertEquals(u.getName(), userDAO.getUserList().get(userDAO.getUserList().size()-1).getName());
    }

某些控制台打印信息

INFO: Using DataSource [org.apache.commons.dbcp2.BasicDataSource@498d318c] of Hibernate SessionFactory for HibernateTransactionManager
    JUNE 02, 2017 4:46:19 afternoon org.springframework.test.context.transaction.TransactionContext startTransaction
INFO: Began transaction (1) for test context [DefaultTestContext@52d6cd34 testClass = UserServiceImplTest, testInstance = com.dxzh.mall.serviceImpl.test.UserServiceImplTest@715d6168, testMethod = testAddUse@UserServiceImplTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@75798d03 testClass = UserServiceImplTest, locations = '{classpath:/services.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.hibernate5.HibernateTransactionManager@c6634d]; rollback [true]
    Fri Jun 02 16:46:19 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
    Hibernate: insert into user (name, password, level) values (?, ?, ?)
    JUNE 02, 2017 4:46:19 afternoon org.springframework.test.context.transaction.TransactionContext endTransaction
INFO: Rolled back transaction for test context [DefaultTestContext@52d6cd34 testClass = UserServiceImplTest, testInstance = com.dxzh.mall.serviceImpl.test.UserServiceImplTest@715d6168, testMethod = testAddUse@UserServiceImplTest, testException = java.lang.RuntimeException, mergedContextConfiguration = [MergedContextConfiguration@75798d03 testClass = UserServiceImplTest, locations = '{classpath:/services.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
    JUNE 02, 2017 4:46:19 afternoon org.springframework.context.support.GenericApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@3ffc5af1: startup date [Fri Jun 02 16:46:13 CST 2017]; root of context hierarchy

1 个答案:

答案 0 :(得分:0)

可悲的是,你在这里混合了一对概念。

您的生产代码直接管理事务,而您的测试代码使用AOP(面向方面​​编程)弹簧注释。

由于生产代码管理事务,测试代码中的AOP注释完全没用:事务规则是生产代码中的规则。

解决方案:在您的生产代码中也使用AOP。让强大且经过良好测试的Spring事务机制来管理事务并忘记自己管理它。像这样:

@Override
@Transactional(transactionManager = "txManager")
public void addUser(User u) {
    // only your bussiness logic here
}

更多信息:here (example)here(Spring manal)

This wikipedia article解释了不同的软件测试方法。您属于集成测试

类别