一起学习
Spring 2.5 TestContext 测试框架用于测试基于 Spring 的程序,TestContext 测试框架和低版本 Spring 测试框架没有任何关系,是一个全新的基于注解的测试框架,为 Spring 推荐使用该测试框架。
概述
Spring 2.5 相比于 Spring 2.0 所新增的最重要的功能可以归结为以下 3 点:
基于注解的 IoC 功能;
基于注解驱动的 Spring MVC 功能;
基于注解的 TestContext 测试框架。
Spring 推荐
开发者使用新的基于注解的 TestContext 测试框架,本文我们将对此进行详细的讲述。
低版本的 Spring 所提供的 Spring 测试框架构在 JUnit 3.8
基础上扩展而来,它提供了若干个测试基类。而 Spring 2.5 所新增的基于注解的 TestContext 测试框架和低版本的测试框架没有任何关系。它采用全新的注解技术可以让 POJO 成为 Spring 的测试用例,除了拥有旧测试框架所有功能外,TestContext 还添加了一些新的功能,TestContext 可以运行在 JUnit 3.8、JUnit 4.4、TestNG 等测试框架下。
直接使用JUnit 测试Spring 程序存在的不足
在拙作《精通 Spring 2.x — 企业应用开发详解》一书中,笔者曾经指出如果直接使用 JUnit 测试基于 Spring 的程序,将存在以下 4 点明显的不足:
导致 Spring 容器多次初始化问题:根据 JUnit 测试用例的调用流程,每执行一个测试方法都会重新创建一个测试用例实例并调用其 setUp() 方法。由于在一般情况下,我们都在 setUp() 方法中初始化 Spring 容器,这意味着测试用例中有多少个测试方法,Spring 容器就会被重复初始化多少次。
需要使用硬编码方式手工获取 Bean:在测试用例中,我们需要通过 ApplicationContext.getBean() 的方法从 Spirng 容器中获取需要测试的目标 Bean,并且还要进行造型操作。
数据库现场容易遭受破坏:测试方法可能会对数据库记录进行更改操作,破坏数据库现场。虽然是针对开发数据库进行测试工作的,但如果数据操作的影响是持久的,将会形成积累效应并影响到测试用例的再次执行。举个例子,假设在某个测试方法中往数据库插入一条 ID 为 1 的 t_user 记录,第一次运行不会有问题,第二次运行时,就会因为主键冲突而导致测试用例执行失败。所以测试用例应该既能够完成测试固件业务功能正确性的检查,又能够容易地在测试完成后恢复现场,做到踏雪无迹、雁过无痕。
不容易在同一事务下访问数据库以检验业务操作的正确性:当测试固件操作数据库时,为了检测数据操作的正确性,需要通过一种方便途径在测试方法相同的事务环境下访问数据库,以检查测试固件数据操作的执行效果。如果直接使用 JUnit 进行测试,我们很难完成这项操作。
Spring 测试框架是专门为测试基于 Spring 框架应用程序而设计的,它能够让测试用例非常方便地和 Spring 框架结合起来,以上所有问题都将迎刃而解。
一个需要测试的 Spring 服务类
在具体使用 TextContext 测试框架之前,我们先来认识一下需要测试的 UserService 服务类。UserService 服务类中拥有一个处理用户登录的服务方法,其代码如下所示:
清单1. UserService.java 需要测试的服务类
package com.baobaotao.service;
import com.baobaotao.domain.LoginLog;
import com.baobaotao.domain.User;
import com.baobaotao.dao.UserDao;
import com.baobaotao.dao.LoginLogDao;
public class UserService{
private UserDao userDao;
private LoginLogDao loginLogDao;
public void handleUserLogin(User user) {
user.setCredits( 5 user.getCredits());
LoginLog loginLog = new LoginLog();
loginLog.setUserId(user.getUserId());
loginLog.setIp(user.getLastIp());
loginLog.setLoginTime(user.getLastVisit());
userDao.updateLoginInfo(user);
loginLogDao.insertLoginLog(loginLog);
}
//省略get/setter方法
}
UserService 需要调用 DAO 层的 UserDao 和 LoginLogDao 以及 User 和 LoginLog 这两个 PO 完成业务逻辑,User 和 LoginLog分别对应 t_user 和 t_login_log 这两张数据库表。
在用户登录成功后调用 UserService 中的 handleUserLogin() 方法执行用户登录成功后的业务逻辑:
登录用户添加 5 个积分(t_user.credits);
登录用户的最后访问时间(t_user.last_visit)和 IP(t_user.last_ip)更新为当前值;
在日志表中(t_login_log)中为用户添加一条登录日志。
这是一个需要访问数据库并存在数据更改操作的业务方法,它工作在事务环境下。
下载本文示例代码
使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架使用Spring 2.5 TestContext 测试框架