package mocktest; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SimpleCalcServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Integer a = Integer.decode(request.getParameter("a")); Integer b = Integer.decode(request.getParameter("b")); int result = a.intValue() + b.intValue(); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print("Result = " + result); out.flush(); } }
这个类是一个Servlet,我们可以通过JUnit的一个扩展:HttpUnit来编写它的测试用例。不过,如何使用HttpUnit进行测试不是本文所讨论的内容。 如果利用Mock Object来为这个类编写单元测试用例的话,问题的实质在于如何构造HttpServletRequest和HttpServletResponse的实例。下面,我们将一一展示如何使用上面提到的工具来解决这个问题: MockObjects 我们有四种方式来利用MockObjects编写测试用例: 1、基于MockObjects的框架编写自己的Mock Object实现并与其他人分享; 2、直接使用MockObjects提供的Mock Object进行测试; 3、使用其中包含的DynaMock模块快速获取Mock Object实例; 4、通过它提供的Helpers对象帮助我们快速构建测试环境。 不过,本文仅关注如何使用DynaMock来编写测试用例[1]:1. public void testSimpleAdditionUsingDynaMock() throws ServletException, IOException { 2. final Mock mockHttpServletRequest = new Mock(HttpServletRequest.class); 3. final Mock mockHttpServletResponse = new OrderedMock(HttpServletResponse.class, 4. "Response with non-default name"); 5. 6. mockHttpServletRequest.expectAndReturn("getParameter", "b", "4"); 7. mockHttpServletRequest.expectAndReturn("getParameter", "a", "3"); 8. 9. final StringWriter output = new StringWriter(); 10. final PrintWriter contentWriter = new PrintWriter(output); 11. 12. mockHttpServletResponse.expect("setContentType", "text/html"); 13. mockHttpServletResponse.expectAndReturn("getWriter", contentWriter); 14. 15. SimpleCalcServlet aServlet = new SimpleCalcServlet(); 16. aServlet.doGet((HttpServletRequest) mockHttpServletRequest.proxy(), 17. (HttpServletResponse) mockHttpServletResponse.proxy()); 18. 19. mockHttpServletRequest.verify(); 20. mockHttpServletResponse.verify(); 21. assertEquals("Output should be an addition", "Result = 7", output.toString()); 22. }
对照“Mock Object”一节所言的“代码样式”,Line2~4即为“创建”Mock Object实例: ●我们使用了两个不同的类来构造Mock Object:一个是Mock,一个是OrderedMock。他俩的异同在于一个不检测接口被调用的次序,一个需要检测接口被调用的次序。 Line6~13为“训练”Mock Object: ●在训练Mock Object的时候,我们调用了它的expectAndReturn()方法。此方法有多个重载。对于测试方法第6行来说,它表达了这样一个意思:被测代码将传入参数“b”来调用mockHttpServletRequest的getParameter()方法;当接收到此消息时,mockHttpServletRequest将返回字符串“4”。 Line15~17为“测试”: ●实际进行测试的时候,通过调用Mock类实例的proxy()方法将Mock Object实例传递给被测代码。 Line19~21为“验证”: ●此时,使用Mock类实例的verify()方法进行一致性验证。 [1] 为了节省篇幅、简单起见,本文只列出JUnit测试用例中test方法的代码。本文地址:http://com.8s8s.com/it/it16751.htm