== 单元测试应用示例——测试Servlet类 == Servlet对象由Web容器创建,它依赖HttpServletRequest,HttpServletResponse,ServletConfig等对象,很难使用Junit进行单元测试.但如果借助Spring测试框架的话,就比较容易了.[[BR]] Spring测试框架提供了MockHttpServletRequest,MockHttpServletResponse,MockServletConfig,等对象,可以很方便地模拟Servlet依赖的环境。[[BR]] AdRegistedServlet在用户在游戏的注册引导页完成注册后,将用户信息统计到数据库.[[BR]] {{{ #!java /** * * @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[[BR]] 然后,我们要模拟HttpServletRequest,HttpServletResponse {{{ #!java @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 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()); } .................. } }}}