在Spring中進(jìn)行集成測(cè)試
在單元測(cè)試時(shí),我們盡量在屏蔽模塊間相互干擾的情況下,重點(diǎn)關(guān)注模塊內(nèi)部邏輯的正確性。而集成測(cè)試則是在將模塊整合在一起后進(jìn)行的測(cè)試,它的目的在于發(fā)現(xiàn)一些模塊間整合的問題。有些功能很難通過模擬對(duì)象進(jìn)行模擬,相反它們往往只能在真實(shí)模塊整合后,才能真正運(yùn)行起來,如事務(wù)管理就是其中比較典型的例子。
按照Spring的推薦(原話:You should not normally use the Spring container for unit tests: simply populate your POJOs in plain JUnit tests!),在單元測(cè)試時(shí),你不應(yīng)該依賴于Spring容器。換言之,你不應(yīng)該在單元測(cè)試時(shí)啟動(dòng)ApplicatonContext并從中獲取 Bean,相反你應(yīng)該通過模擬對(duì)象完成單元測(cè)試。而集成測(cè)試的前提則是事先裝配好模塊和模塊之間的關(guān)聯(lián)類,如將DAO層真實(shí)的UserDao和 LoginLogDao裝配到UserServiceImpl再進(jìn)行測(cè)試。具體裝配工作是在Spring配置文件中完成的,因此在一般情況下,集成測(cè)試需要啟動(dòng)Spring容器,你可以在測(cè)試類中簡(jiǎn)單地從Spring容器中取出目標(biāo)Bean進(jìn)行測(cè)試。
需要測(cè)試的業(yè)務(wù)接口
假設(shè)我們的應(yīng)用中擁有一個(gè)UserService業(yè)務(wù)層接口,它擁有4個(gè)業(yè)務(wù)方法,其代碼如下所示:
代碼清單1 UserServie接口
- package com.baobaotao.service;
- import com.baobaotao.domain.User;
- import org.springframework.transaction.annotation.Transactional;
- @Transactional
- public interface UserService {
- boolean hasMatchUser(String userName,String password);
- User findUserByUserName(String userName);
- void loginSuccess(User user);
- void registerUser(User user);
- }
我們通過UserServiceImpl對(duì)UserService提供了實(shí)現(xiàn):
代碼清單2 UserServiceImpl實(shí)現(xiàn)UserService接口
- package com.baobaotao.service;
- import com.baobaotao.dao.LoginLogDao;
- import com.baobaotao.dao.UserDao;
- import com.baobaotao.domain.LoginLog;
- import com.baobaotao.domain.User;
- public class UserServiceImpl implements UserService {
- private UserDao userDao;
- private LoginLogDao loginLogDao;
- public boolean hasMatchUser(String userName, String password) {
- int matchCount =userDao.getMatchCount(userName, password);
- return matchCount > 0;
- }
- public User findUserByUserName(String userName) {
- return userDao.findUserByUserName(userName);
- }
- public void loginSuccess(User user) {
- user.setCredits( 5 + user.getCredits());
- LoginLog loginLog = new LoginLog();
- loginLog.setUserId(user.getUserId());
- loginLog.setIp(user.getLastIp());
- loginLog.setLoginDate(user.getLastVisit());
- userDao.updateLoginInfo(user);
- loginLogDao.insertLoginLog(loginLog);
- }
- public void setLoginLogDao(LoginLogDao loginLogDao) {
- this.loginLogDao = loginLogDao;
- }
- public void setUserDao(UserDao userDao) {
- this.userDao = userDao;
- }
- }
UserServiceImpl引用了兩個(gè)DAO層的類(UserDao和LoginLogDao)共同實(shí)現(xiàn)UserService的接口,在UserServiceImpl開放使用之前,我們有必須對(duì)其進(jìn)行集成測(cè)試,以保證實(shí)現(xiàn)邏輯的正確性。
【編輯推薦】