Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1370982
  • 博文数量: 205
  • 博客积分: 6732
  • 博客等级: 准将
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-04 17:59
文章分类

全部博文(205)

文章存档

2016年(1)

2015年(10)

2014年(1)

2013年(39)

2012年(23)

2011年(27)

2010年(21)

2009年(55)

2008年(28)

我的朋友

分类: Java

2011-07-14 10:39:49

单元测试现在越来越被广泛重视起来,而Spring更是将时下比较流行的Junit开元测试框架进行整合下面我简单的介绍一下在Sping中该如何对代码进行单元测试(本节会认为读者已经具备了Junit基础方面的知识)。按照Spring的推荐,在单元测试时不应该依赖于Spring容器,也就是说不应该在单元测试是启动ApplicationContext并从中获取Bean,相反应该通过模拟对象完成单元测试。而Spring就提供了这样一个类供大家继承。下面来看看示例代码:
1)自动装配的测试用例
代码清单1
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tony.web.dao.FooDao;
 
@Service
public class FooService {
    @Autowired
    private FooDao dao;
    public String save(String name){
       if(name == null || "".equals(name))
           throw new RuntimeException("Name is null");
       return dao.save(name);
    }
}
import org.springframework.stereotype.Repository;
@Repository
public class FooDao {
    public String save(String name){
       return "success";
    }
}
import org.springframework.test.
AbstractDependencyInjectionSpringContextTests;
import com.tony.web.service.FooService;
public class MyTest extends AbstractDependencyInjectionSpringContextTests{
    protected FooService fooService;
    //set方法
    public void setFooService(FooService fooService) {
       this.fooService = fooService;
    }
    //指定Spring配置文件的位置
    protected String[] getConfigLocations(){
       return new String[]{"spring-config-beans.xml"};
    }
    //测试方法
    public void testSave(){
       String str = this.fooService.save("Tony");
       System.out.print(str);
       assertEquals("success", str);
    }
}
xml version="1.0" encoding="UTF-8"?>
<beans xmlns=">
    <context:component-scan base-package="com.tony"/>
beans>
代码清单1中定义了FooService.javaFooDao.java两个Bean已经使用 @Autowired进行了装配,我们的单元测试类MyTest继承了
AbstractDependencyInjectionSpringContextTests类,配置好fooServiceset方法并且指定Spring配置文件的位置后,当测试用例运行时我们需要的fooService会自动注入进来,我们只要在testSave方法中直接使用就可以了,还有两外一种写法
代码清单2
public class MyTest extends AbstractDependencyInjectionSpringContextTests{
    protected FooService fooService;
   
    public MyTest(){
       //启用直接对属性变量进行注入的机制
this.setPopulateProtectedVariables(true);
    }
    protected String[] getConfigLocations(){
       return new String[]{"spring-config-beans.xml"};
    }
    public void testSave(){
       String str = this.fooService.save("Tony");
       System.out.print(str);
       assertEquals("success", str);
    }
}
代码清单2中我们移除了set方法,增加了一个构造函数,在构造函数中调用父类的方法启用直接对属性变量进行注入的机制。有时我们测试的时候会操作数据库插入一条记录,由于我们不会每次都修改测试的数据,当我们再次插入同样的数据时数据库肯定会要报错了,此时我们需要既能测试又能不让测试的数据在数据库中起作用,Spring就知道我们的这个需要,为我们准备了AbstractTransactionalSpringContextTests这个类。
代码清单3
import org.springframework.test.
AbstractTransactionalSpringContextTests;
import com.tony.web.service.FooService;
public class MyTest extends AbstractTransactionalSpringContextTests{
    protected FooService fooService;
    public MyTest(){
       this.setPopulateProtectedVariables(true);
    }
    protected String[] getConfigLocations(){
       return new String[]{"spring-config-beans.xml"};
    }
//测试方法中的数据操作将在方法返回前被回滚,不会对数据库产生永久性数据操作,下一//次运行该测试方法时,依旧可以成功运行.
    public void testSave(){
       String str = this.fooService.save("Tony");
       System.out.print(str);
       assertEquals("success", str);
    }
}
    这样就可以在方法返回之前将测试数据回滚,以保证下次单元测试的成功。
阅读(1363) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~