我正在尝试用spring、junit测试 DAO 的方法,我看到网上的一些做法是使用 spring 的声明式事务管理(即@Transactional)进行事务操作,说是这样在测试完成之后能够spring会让测试的方法回滚,从而达到测试的目的。
然后我按照这一做法对dao中添加操作的方法进行了测试,发现事务进行提交后,回滚没有成功,数据库中多出来了我进行测试的数据。一开始我以为是spring没有进行回滚,但是后面观察控制台打印信息发现是有rollback信息的,但是为什么会失败呢,就不清楚。我查到一些相关的方案,但是我发现并没能解决我的问题。很困扰,特来请教各位,望不吝指教。
以下是我的代码和相应配置
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; //自动装配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
用dbunit 结合 spring-test 去测试
Transactional是service层事务,用了就不必在DAO层写事务了