单元测试应用示例——测试Servlet类
Servlet对象由Web容器创建,它依赖HttpServletRequest,HttpServletResponse?,ServletConfig等对象,很难使用Junit进行单元测试.但如果借助Spring测试框架的话,就比较容易了.
Spring测试框架提供了MockHttpServletRequest,MockHttpServletResponse?,MockServletConfig?,等对象,可以很方便地模拟Servlet依赖的环境。
AdRegistedServlet在用户在游戏的注册引导页完成注册后,将用户信息统计到数据库.
/**
*
* @author ChenYang
* Date: 2011-12-30
*/
public class AdRegistedServlet extends HttpServlet {
private static Log log = LogFactory.getLog(AdRegistedServlet.class);
private ApplicationContext applicationContext = null;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doPost(req,res);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String accountId = req.getParameter("accountId");
String returnUrl = req.getParameter("return");
if(StringUtils.isBlank(accountId)){
return;
}
Passport passport = (Passport) applicationContext.getBean("passport");
try {
Session realmSession = passport.login(req, res);
log.info(realmSession.getAccountId());
} catch (LoginException e) {
log.error(e.getMessage());
}
String srcid = req.getParameter("srcid");
if(StringUtils.isBlank(srcid)){
res.sendRedirect(returnUrl);
}else{
AdTypeDAO adTypeDAO = (AdTypeDAO) applicationContext.getBean("adTypeDAO");
AdType adType = adTypeDAO.find(Long.valueOf(srcid));
if(adType == null){
log.info("非法的推广来源:"+srcid);
res.sendRedirect(returnUrl);
return;
}
String ip = IpUtils.getIp(req);
AdRequest ad_request = new AdRequest();
ad_request.setSrcId(StringUtils.isBlank(srcid) ? -1 : Long.valueOf(srcid));
ad_request.setSrc(adType == null ? "" : adType.getSrc());
ad_request.setIp(ip);
String referer = req.getHeader("Referer");
if(referer == null){
return;
}
long gameid = AdRequestUtils.refererToGameId(referer);
if(gameid == 0){
log.info("未配置游戏id的请求来源:"+referer);
res.sendRedirect(returnUrl);
return;
}
ad_request.setGameid(gameid);
ad_request.setUserid(Long.valueOf(accountId));
Date now = new Date();
ad_request.setCreateAt(now);
ad_request.setStatus(AdRequestUtils.REGISTED_STATUS);
ad_request.setReferer(req.getParameter("referer"));
AdRequestDAO adRequestDAO = (AdRequestDAO) applicationContext.getBean("adRequestDAO");
adRequestDAO.createAdRequest(ad_request);
res.sendRedirect(returnUrl);
}
}
@Override
public void init(ServletConfig config) throws ServletException {
if(applicationContext == null){
ServletContext ctx = config.getServletContext();
this.applicationContext = WebApplicationContextUtils.getWebApplicationContext(ctx);
}
}
}
要测试doPost()方法的话,首先要准备applicationContext,我们可以通过继承AbstractTransactionalJUnit4SpringContextTests,以获得ApplicationContext
然后,我们要模拟HttpServletRequest,HttpServletResponse?
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class AdRegistedServletTest extends AbstractTransactionalJUnit4SpringContextTests{
@Before
public void init(){
Env env = EnvUtils.getEnv();
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("X-Forwarded-For", "192.168.20.92");
request.addHeader("X-Real-IP", "192.168.20.92");
request.setRemoteAddr("192.168.20.92");
env.setRequest(request);
}
@After
public void destory(){
EnvUtils.removeEnv();
}
@Autowired
CacheClient cacheClient;
@Autowired
private AdTypeDAO adTypeDAO;
/**
* 测试正常流程
* @throws Exception
*/
@Test
public void doPost() throws Exception {
final AdRegistedServlet adRegistedServlet = new AdRegistedServlet();
adRegistedServlet.setApplicationContext(applicationContext);
//模拟ServletConfig
MockServletConfig config = new MockServletConfig();
adRegistedServlet.init(config);
//模拟HttpServletRequest
final MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Referer", "http://g2.pcgames.com.cn/popularize/sxd_register.jsp");
request.addHeader("X-Forwarded-For", "192.168.20.92");
request.addHeader("X-Real-IP", "192.168.20.92");
request.setRemoteAddr("192.168.20.92");
AdType adType = new AdType();
adType.setSrc("wltg");
long srcid = adTypeDAO.create(adType);
request.addParameter("srcid", ""+srcid);
request.addParameter("accountId", "393648562");
request.addParameter("referer", "http://www.sina.com.cn");
request.addParameter("return", "http://g2.pcgames.com.cn");
//模拟HttpServletResponse
final MockHttpServletResponse response = new MockHttpServletResponse();
Mockery ctx = new Mockery();
final EnvInterface env = ctx.mock(EnvInterface.class);
request.setAttribute("env", env);
ctx.checking(new Expectations(){
{
one(env).getRoot();
will(returnValue("http://g2.pcgames.com.cn"));
}
});
adRegistedServlet.doPost(request, response);
AdRequestDAO adRequestDAO = (AdRequestDAO) applicationContext.getBean("adRequestDAO");
List<AdRequest> list = adRequestDAO.query("SELECT * FROM ad_request WHERE userid = 393648562 AND ip = '192.168.20.92' AND srcid = "+srcid);
//断言doPost()后,与我们期望的结果一致
Assert.assertEquals(1,list.size());
}
..................
}
![(please configure the [header_logo] section in trac.ini)](http://www1.pconline.com.cn/hr/2009/global/images/logo.gif)