单元测试应用示例——测试Filter
游戏大厅中的AdminAuthFilter,用来检验用户有没有防问被保护的jsp权限,代码如下
@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方法中还依赖
Env对象,该对象非常复杂,非常难模拟。我们的测试似乎很难进行了,但我们如果使用了jMock的话,也能解决模拟Env对象,jMock模拟一个对象时,要求该对象必须实现某个接口,然后模拟该接口。
而Env对象并未实现任何接口,为了编写单元测试,我们让Env去实现EnvInterface接口
/**
*
* @author ChenYang
* Date: 2012-1-10
*/
public interface EnvInterface {
public User getUser();
public UserInfo getUserInfo();
public String getRoot();
public boolean isAdmin();
}
Env实现EnvInterface 接口
public class Env implements EnvInterface{
..................
}
这次我们不选择Spring测试框架的提供Web模拟对象,改用jmock去模拟Web对象
/**
* 测试用户没有登陆
* @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);
}
![(please configure the [header_logo] section in trac.ini)](http://www1.pconline.com.cn/hr/2009/global/images/logo.gif)