== 单元测试应用示例——测试Filter == 游戏大厅中的AdminAuthFilter,用来检验用户有没有防问被保护的jsp权限,代码如下[[BR]] {{{ #!java @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; //请求路径 String requestURI = request.getRequestURI(); EnvInterface env = (EnvInterface) req.getAttribute("env"); if(env.getUserInfo().getId() <= 0){ log.info("非法访问:"+requestURI); response.sendRedirect(env.getRoot()+"/admin/login.jsp"); return; }else{ if(Pattern.matches(".+/admin/game/action/.+", requestURI)){ //管理员才有权限访问该目录下的资源 if(!env.isAdmin()){ log.info("无权限访问:"+request.getRequestURI()); response.sendRedirect(env.getRoot()+"/admin/login.jsp"); }else{ chain.doFilter(req, resp); } }else{ chain.doFilter(req, resp); } } } }}} filter依赖HttpServletRequest,HttpServletResponse,FilterChain等对象,比较难测试,我们可以通过使用Spring测试框架提供的模拟对象,来辅助我们使用junit来测试。我们看到该doFilter方法中还依赖[[BR]] Env对象,该对象非常复杂,非常难模拟。我们的测试似乎很难进行了,但我们如果使用了jMock的话,也能解决模拟Env对象,jMock模拟一个对象时,要求该对象必须实现某个接口,然后模拟该接口。[[BR]] 而Env对象并未实现任何接口,为了编写单元测试,我们让Env去实现EnvInterface接口 {{{ #!java /** * * @author ChenYang * Date: 2012-1-10 */ public interface EnvInterface { public User getUser(); public UserInfo getUserInfo(); public String getRoot(); public boolean isAdmin(); } }}} Env实现EnvInterface 接口 {{{ #!java public class Env implements EnvInterface{ .................. } }}} 这次我们不选择Spring测试框架的提供Web模拟对象,改用jmock去模拟Web对象 {{{ #!java /** * 测试用户没有登陆 * @throws Exception */ @Test public void doFilter() throws Exception { Mockery ctx = new Mockery(); //jMock模拟HttpServletRequest final HttpServletRequest request = ctx.mock(HttpServletRequest.class); //jMock模拟HttpServletResponse final HttpServletResponse response = ctx.mock(HttpServletResponse.class); //jMock模拟FilterChain final FilterChain chain = ctx.mock(FilterChain.class); //jMock模拟chain final EnvInterface env = ctx.mock(EnvInterface.class); final UserInfo user = new UserInfo(); ctx.checking(new Expectations(){ { //期望request.getAttribute("env");会调用一次,并返回env one(request).getAttribute("env"); will(returnValue(env)); //期望request.getRequestURI();会调用一次,并返回"http://g2.pcgames.com.cn/admin/game/game.jsp" one(request).getRequestURI(); will(returnValue("http://g2.pcgames.com.cn/admin/game/game.jsp")); //期望env.getUserInfo();会调用一次,并返回user one(env).getUserInfo(); will(returnValue(user)); //期望env.getRoot();会调用一次,并返回"http://g2.pcgames.com.cn" one(env).getRoot(); will(returnValue("http://g2.pcgames.com.cn")); //期望response.sendRedirect("http://g2.pcgames.com.cn/admin/login.jsp");会调用一次 one(response).sendRedirect("http://g2.pcgames.com.cn/admin/login.jsp"); } }); AdminAuthFilter filter = new AdminAuthFilter(); filter.doFilter(request, response, chain); } }}}