清单 3. AccountService.Java
- package service;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.Springframework.beans.factory.annotation.Autowired;
-
- import DAO.AccountDao;
- import domain.Account;
-
- public class AccountService {
- private static final Log log = LogFactory.getLog(AccountService.class);
-
- @Autowired
- private AccountDao accountDao;
-
- public Account getAccountById(int id) {
- return accountDao.getAccountById(id);
- }
-
- public void insertIfNotExist(Account account) {
- Account acct = accountDao.getAccountById(account.getId());
- if(acct==null) {
- log.debug("No "+account+" found,would insert it.");
- accountDao.saveAccount(account);
- }
- acct = null;
- }
-
- }
|
AccountService 包括下列方法:
● getAccountById:根据 Id 查询账号信息
● insertIfNotExist:根据传入的对象插入数据库
其依赖的 DAO 对象 accountDao 是通过 Spring 注释标签 @Autowired 自动注入的。
清单 4. Spring 配置文件
上述几个类的依赖关系是通过 Spring 进行管理的,配置文件如下:
- <beans xmlns="http://www.Springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.Springframework.org/schema/context"
- xsi:schemaLocation="http://www.Springframework.org/schema/beans
-
- http://www.Springframework.org/schema/beans/Spring-beans-3.0.xsd
-
-
- http://www.Springframework.org/schema/context
-
- http://www.Springframework.org/schema/context/Spring-context-3.0.xsd ">
-
- <context:annotation-config/>
- <bean id="datasource">
- <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
- <property name="url" value="jdbc:hsqldb:hsql://localhost" />
- <property name="username" value="sa" />
- <property name="password" value="" />
- </bean>
- <bean id="initer" init-method="init">
- </bean>
- <bean id="accountDao" depends-on="initer">
- <property name="dataSource" ref="datasource" />
- </bean>
- <bean id="accountService">
- </bean>
- </beans>
|
注意其中的“<context:annotation-config/>”的作用,这个配置启用了 Spring 对 Annotation 的支持,这样在我们的测试类中 @Autowired 注释才会起作用(如果用了 Spring 测试框架,则不需要这样的配置项,稍后会演示)。另外还有一个 accountDao 依赖的 initer bean, 这个 bean 的作用是加载 log4j 日志环境,不是必须的。
另外还有一个要注意的地方,就是 datasource 的定义,由于我们使用的是 Spring Jdbc Template,所以只要定义一个 org.Springframework.jdbc.datasource.DriverManagerDataSource 类型的 datasource 即可。这里我们使用了简单的数据库 HSQL、Single Server 运行模式,通过 JDBC 进行访问。实际测试中,大家可以选择 Oracle 或者 DB2、Mysql 等。
好,万事具备,下面我们来用 Junit4 框架测试 accountService 类。代码如下:
清单 5. AccountServiceOldTest.Java
- package service;
-
- import static org.Junit.Assert.assertEquals;
-
- import org.Junit.BeforeClass;
- import org.Junit.Test;
- import org.Springframework.context.ApplicationContext;
- import org.Springframework.context.support.ClassPathXmlApplicationContext;
-
- import domain.Account;
-
- public class AccountServiceOldTest {
- private static AccountService service;
-
- @BeforeClass
- public static void init() {
- ApplicationContext
- context = new ClassPathXmlApplicationContext("config/Spring-db-old.xml");
- service = (AccountService)context.getBean("accountService");
- }
-
- @Test
- public void testGetAcccountById() {
- Account acct = Account.getAccount(1, "user01", 18, "M");
- Account acct2 = null;
- try {
- service.insertIfNotExist(acct);
- acct2 = service.getAccountById(1);
- assertEquals(acct, acct2);
- } catch (Exception ex) {
- fail(ex.getMessage());
- } finally {
- service.removeAccount(acct);
- }
- }
- }
|
注意上面的 Junit4 注释标签,第一个注释标签 @BeforeClass,用来执行整个测试类需要一次性初始化的环境,这里我们用 Spring 的 ClassPathXmlApplicationContext 从 XML 文件中加载了上面定义的 Spring 配置文件,并从中获得了 accountService 的实例。第二个注释标签 @Test 用来进行实际的测试。
测试过程:我们先获取一个 Account 实例对象,然后通过 service bean 插入数据库中,然后通过 getAccountById 方法从数据库再查询这个记录,如果能获取,则判断两者的相等性;如果相同,则表示测试成功。成功后,我们尝试删除这个记录,以利于下一个测试的进行,这里我们用了 try-catch-finally 来保证账号信息会被清除。
执行测试:(在 Eclipse 中,右键选择 AccountServiceOldTest 类,点击 Run as Junit test 选项),得到的结果如下:
执行测试的结果
在 Eclipse 的 Junit 视图中,我们可以看到如下的结果:
图 2. 测试的结果
对于这种不使用 Spring test 框架进行的单元测试,我们注意到,需要做这些工作:
● 在测试开始之前,需要手工加载 Spring 的配置文件,并获取需要的 bean 实例
● 在测试结束的时候,需要手工清空搭建的数据库环境,比如清除您插入或者更新的数据,以保证对下一个测试没有影响