最近一個項目使用的是struts2+Spring3+mybatis3的技術框架,由于開發人員都不熟悉如何進行單元測試,今天有空,簡單研究了一下如何用junit4來測試基于這個框架的代碼。由于struts的action只是負責前臺的請求轉發,而所有的業務都是在service層處理,因此一般情況下只需對service進行單元測試,而不需要對action進行單元測試。下面介紹一個簡單的例子:
開發環境:
System:Windows xp
IDE:eclipse Java EE 3.6
Database:MySQL
開發依賴庫:
JavaEE5、Spring 3.0.5、Mybatis 3.0.4、myBatis-spring-1.0、junit4.8.1
一、準備工作:
1、
下載jar包Spring3 jar
下載:
http://ebr.springsource.com/repository/app/library/version/detail?name=org.springframework.spring&version=3.0.5.RELEASE
MyBatis3 jar 下載:
http://www.mybatis.org/java.html
junit 4 jar下載:
http://www.junit.org/
2、 添加的jar包如下:

3、創建mysql的數據庫表,步驟如下:
1、進入mysql的安裝路徑,假設在:C:\Program Files\MySQL\MySQL Server 5.1\bin; 2、輸入命令:mysql -uroot -p,enter,輸入密碼:admin; 3、mysql>use test; 5、mysql>grant all privileges on test.* to test@'localhost' identified by 'test'; 6、mysql>flush privileges; 4、mysql> create table account_bak(account_id int not null auto_increment, username varchar(20), password varchar(20), create_time datetime, primary key(account_id));
|
二、spring 和mybatis整合
1、在eclipse中創建一個java project,目錄結構如下:

這是一個標準的maven工程的目錄結構,下面逐一介紹上圖涉及到的文件。
2、創建mybatis的配置文件mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration> |
上面的配置文件中,可以加入一些公共、常用的MyBatis方面的全局配置。如handler、objectFactory、plugin、以及mappers的映射路徑(由于在spring配置文件spring.xml中的SqlSessionFactoryBean有配置mapper的location,這里就不需要配置)等。這個文件名稱和下面的spring.xml中的configLocation中的值對應,不是隨便寫的。3、創建spring的配置文件spring.xml
4、
JavaBean(Model、Entity)相關類、及mybatis 的mapper對象
javabean:
package com.glen.model;
import java.io.Serializable; import java.util.Date;
public class Account implements Serializable {
private static final long serialVersionUID = -7970848646314840509L; private Integer accountId; private String username; private String password; private Date createTime;
public Account() { super(); } //下面是getter、setters |
account-resultMap.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="accountMap">
<resultMap type="com.hoo.entity.Account" id="accountResultMap">
<id property="accountId" column="account_id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="createTime" column="create_time"/>
</resultMap>
</mapper>
|
account-mapper.xml
5、創建dao:
package com.glen.dao;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.stereotype.Repository;
import com.glen.model.Account;
public class AccountDao {
private SqlSessionFactory sessionFactory;
public AccountDao() {
}
public SqlSessionFactory getSessionFactory() { return sessionFactory; }
public void setSessionFactory(SqlSessionFactory sessionFactory) { this.sessionFactory = sessionFactory; }
public void insert(Account account) {
SqlSession session = sessionFactory.openSession(); session.insert("account.add", account); } public Account getAccountById(Account account) { SqlSession session = sessionFactory.openSession(); Account accountFromDb = (Account)session.selectOne("account.get", account); return accountFromDb; } }
|
6、創建service:
package com.glen.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.glen.dao.AccountDao; import com.glen.model.Account;
public class AccountService { private AccountDao accountDao; /** * 新增一個帳戶。 * @param account */ public void insertAccount(Account account) { accountDao.insert(account); }
/** * 根據帳戶ID查找帳戶信息 * @param account * @return */ public Account getAccountById(Account account) { return accountDao.getAccountById(account); } public AccountDao getAccountDao() { return accountDao; }
public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } }
|
Ok,至此spring 和mybatis就整合好了。
三、用junit進行單元測試
在src/test/java目錄下,創建一個測試類:TestAccountService:
package com.glen.service;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull;
import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;
import com.glen.model.Account;
public class TestAccountService { Logger logger = Logger.getLogger("TestAccountService"); AccountService service = null;
@Before public void init() { ApplicationContext aCtx = new FileSystemXmlApplicationContext( "classpath:spring.xml"); AccountService service = (AccountService) aCtx .getBean("accountService"); assertNotNull(service); this.service = service;
} @Test public void testInsertAccount() {
// 創建一個帳戶 Account account = new Account(); // account.setAccountId(1); account.setUsername("selina"); account.setPassword("123456"); //將創建的帳戶插入到數據庫中 service.insertAccount(account); logger.debug("account id: " + account.getAccountId()); //從數據庫獲取剛才插入的帳戶 Account accountFromDb = service.getAccountById(account); assertNotNull(accountFromDb); assertEquals(account.getAccountId(), accountFromDb.getAccountId()); }
} |
測試通過,顯示如下界面:

四、使用spring的標記來注入對象
如上所述,我們在spring的配置文件spring.xml中,定義了兩個業務模塊相關的bean,accountDao和accountService,但是在實際項目中,這樣的dao和service會非常多,如果每個都要這樣定義,會造成配置文件的體積過大,可閱讀性和可維護性都會變差。
那么如何對spring.xml進行瘦身呢?有兩種方案,第一種方案是分模塊開發,對于模塊內部的bean,寫在對應模塊內部的spring配置文件中,如:spring-account.xml;第二種方案,就是使用spring的標記。下面我想說說的就是,用spring的標記:@Service @Repository @Resource來實現對象的注入。在上面這個例子基礎上,做以下步驟的修改:
1、注釋掉spring.xml中的兩個bean:accountDao和accountService的定義
<!-- <bean id="accountDao" class="com.glen.dao.AccountDao"> <property name="sessionFactory" ref="sqlSessionFactory"/> </bean> <bean id="accountService" class="com.glen.service.AccountService"> <property name="accountDao" ref="accountDao"/> </bean> --> |
2、在AccountDao類中添加兩個標記:@Repository和 @Resource,
@Repository public class AccountDao {
@Resource private SqlSessionFactory sessionFactory; |
這里添加
@Repository標記,相當于在spring.xml中定義了一個bean,bean的id為這個類對象名稱的第一個字母改成小寫后的字符串,即:accountDao。添加
@Resource標記,相當于在accountDao這個bean中,引用了一個“sqlSessionFactory”。
3、在AccountService類中添加兩個標記:@Service 和 @Resource:
@Service public class AccountService { @Resource private AccountDao accountDao; |
4、運行TestAccountService,同樣測試通過。