search

Home  >  Q&A  >  body text

java - unit testing, how to let spring manage transactions without polluting the database

I am trying to use spring, junit to test the DAO method. I have seen some methods on the Internet that use spring's declarative transaction management (i.e. @Transactional) for transaction operations. , saying that after the test is completed, spring will roll back the test method, thereby achieving the purpose of testing.
Then I followed this approach to test the method of adding operations in dao, and found that after the transaction was submitted, the rollback was not successful, and there was extra data in the database that I tested. At first I thought it was because spring did not perform rollback, but later I observed the console print information and found that there was rollback information, but why it failed was not clear. I found some related solutions, but I found that they didn't solve my problem. I'm very troubled, so I came here to ask you for help. I hope you can give me some advice.

The following is my code and corresponding configuration

@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 ;
    }
<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;  //自动装配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());
    }
信息: Using DataSource [org.apache.commons.dbcp2.BasicDataSource@498d318c] of Hibernate SessionFactory for HibernateTransactionManager
六月 02, 2017 4:46:19 下午 org.springframework.test.context.transaction.TransactionContext startTransaction
信息: 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 (?, ?, ?)
六月 02, 2017 4:46:19 下午 org.springframework.test.context.transaction.TransactionContext endTransaction
信息: 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]]].
六月 02, 2017 4:46:19 下午 org.springframework.context.support.GenericApplicationContext doClose
信息: Closing org.springframework.context.support.GenericApplicationContext@3ffc5af1: startup date [Fri Jun 02 16:46:13 CST 2017]; root of context hierarchy
阿神阿神2724 days ago1084

reply all(2)I'll reply

  • 我想大声告诉你

    我想大声告诉你2017-06-12 09:27:30

    Use dbunit combined with spring-test to test

    reply
    0
  • typecho

    typecho2017-06-12 09:27:30

    Transactional is a service layer transaction. If you use it, you don’t have to write transactions at the DAO layer

    reply
    0
  • Cancelreply