论坛首页 Java企业应用论坛

刚发现Spring的很好东东:Mock和基于Spring容器管理事务的测试

浏览 7538 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-03-08  
也许我孤陋寡闻,我是最近才发现的。
1.Spring Mock。
  Mock主要用于测试Controller(or Action),Controller等同于一个Servlet,要测试它里面的方法,必须至少传入HttpRequest和HttpResponse
两个类的实例作为参数参数,直接new 一个HttpRequest是豪无意义的,必须使用mock。
  Spring的mock那个包就提供了HttpRequest、HttpResponse、HttpSession的mock,测试controller时就可以直接new一个对象!
完整的测试代码Demo如下:
package org.ggyy.web.test;

import junit.framework.TestCase;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ggyy.bo.Cat;
import org.ggyy.web.ctrl.CatController;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.ModelAndView;

public class ListCatTest extends TestCase {
    private static Log log = LogFactory.getLog(ListCatTest.class);;

    private XmlWebApplicationContext ctx;

    public void setUp(); {
        String[] paths = {
                "file:/d:/eclipse/workspace/cat/WebRoot/WEB-INF/applicationContext.xml",
                "file:/d:/eclipse/workspace/cat/WebRoot/WEB-INF/pet-servlet.xml" };
        ctx = new XmlWebApplicationContext();;
        ctx.setConfigLocations(paths);;
        ctx.setServletContext(new MockServletContext(""););;
        ctx.refresh();;
    }

    public void testGetUsers(); throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest();;
        MockHttpServletResponse response = new MockHttpServletResponse();;
        request.addParameter("parentId", "2");;
        CatController c = (CatController); ctx.getBean("catController");;
        ModelAndView mav = c.listCatHandler(request, response);;
        Map m = mav.getModel();;
}
}

catController是MultiActionController,listCatHandler是其中的一个action。这里使用了绝对路径: "file:/d:/eclipse/workspace/cat/WebRoot/WEB-INF/pet-servlet.xml"。相对路径好像调试不出来。

2.基于Spring容器管理事务的测试--可以我表述不是很准确^_^

    对于service层和dao的测试一般都是在实际的数据库中进行测试的,假如你不想使得测试对原来数据库造成任何影响,可以使用这种测试策略。整个测试是在Spring管理的事务中进行的,测试完毕,可以选择提交事务,也可以不提交事务,也就是说测试完后对原来的数据库的记录不造成任何影响。
  这种测试策略最为诱人的还是:当测试不通过,也就是抛出异常时,事务可以自动回滚的!我以前测试前要清空数据库,测试不通过时测试用例后面的delete方法不能运行,我不得不手工的删除这些数据。
  对于测试用例所依赖的bean,声明该bean的一个setter方法spring就可以自动的注入一个实例--很有意思,和ejb3.0类似。
我从pdf文档考下来一个demo供大家观赏:
public abstract class AbstractClinicTests extends AbstractTransactionalDataSourceSpringContextTests {
protected Clinic clinic;
public void setClinic(Clinic clinic); {
this.clinic = clinic;
}
public void testGetVets(); {
Collection vets = this.clinic.getVets();;
assertEquals("JDBC query must show the same number of vets",
jdbcTemplate.queryForInt("SELECT COUNT(0); FROM VETS");,
vets.size(););;
Vet v1 = (Vet); EntityUtils.getById(vets, Vet.class, 2);;
assertEquals("Leary", v1.getLastName(););;
assertEquals(1, v1.getNrOfSpecialties(););;
assertEquals("radiology", ((Specialty); v1.getSpecialties();.get(0););.getName(););;
Vet v2 = (Vet); EntityUtils.getById(vets, Vet.class, 3);;
assertEquals("Douglas", v2.getLastName(););;
assertEquals(2, v2.getNrOfSpecialties(););;
assertEquals("dentistry", ((Specialty); v2.getSpecialties();.get(0););.getName(););;
assertEquals("surgery", ((Specialty); v2.getSpecialties();.get(1););.getName(););;
}

上面的clinic实例是自动注入的,
   发表时间:2005-03-08  
我也是昨天才注意到,尤其是事务部分的,spring1.1.1版本加进去的。看了看Rod的想法真的很不错。对于结合测试是一个很好的工具类。
0 请登录后投票
   发表时间:2005-03-09  
写的好,以前没接触过Mock,看了这个文章有了了解.

如果测试的是Webwork 或Struts的Action,用这个抽象测试类也可以做到么
0 请登录后投票
   发表时间:2005-03-10  
我觉得这个主要是用于DAO的集成测试,
把DAO放在真实的数据库环境中进行测试。
至于action似乎用不到吧。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics