EasyMock使单元测试更加容易

发表于:2008-6-20 15:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试论坛

  单元测试是XP极力推荐的测试驱动开发模式,是保证软件质量的重要方法。尽管如此,对许多类的单元测试仍然是极其困难的,例如,对数据库操作的类进行测试,如果不准备好数据库环境以及相关测试数据,是很难进行单元测试的;再例如,对需要运行在容器内的Servlet或EJB组件,脱离了容器也难于测试。

  幸运的是,Mock Object可以用来模拟一些我们需要的类,这些对象被称之为模仿对象,在单元测试中它们特别有价值。

  Mock Object用于模仿真实对象的方法调用,从而使得测试不需要真正的依赖对象。Mock Object只为某个特定的测试用例的场景提供刚好满足需要的最少功能。它们还可以模拟错误的条件,例如抛出指定的异常等。

  目前,有许多可用的Mock类库可供我们选择。一些Mock库提供了常见的模仿对象,例如:HttpServletRequest,而另一些Mock库则提供了动态生成模仿对象的功能,本文将讨论使用EasyMock动态生成模仿对象以便应用于单元测试。

  到目前为止,EasyMock提供了1.2版本和2.0版本,2.0版本仅支持Java SE 5.0,本例中,我们选择EasyMock 1.2 for Java 1.3版本进行测试,可以从http://www.easymock.org下载合适的版本。

  我们首先来看一个用户验证的LoginServlet类:

  /**
  * LoginServlet.java
  * Author: Liao Xue Feng,www.crackj2ee.com
  */
  package com.crackj2ee.test.mock;
  import java.io.*;
  import javax.servlet.*;
  import javax.servlet.http.*;
  public class LoginServlet extends HttpServlet {
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String username = request.getParameter("username");
  String password = request.getParameter("password");
  // check username & password:
  if("admin".equals(username) && "123456".equals(password)) {
  ServletContext context = getServletContext();
  RequestDispatcher dispatcher = context.getNamedDispatcher("dispatcher");
  dispatcher.forward(request, response);
  }
  else {
  throw new RuntimeException("Login failed.");
  }
  }
  }

  这个Servlet实现简单的用户验证的功能,若用户名和口令匹配“admin”和“123456”,则请求被转发到指定的dispatcher上,否则,直接抛出RuntimeException。

  为了测试doPost()方法,我们需要模拟HttpServletRequest,ServletContext和RequestDispatcher对象,以便脱离J2EE容器来测试这个Servlet。

  我们建立TestCase,名为LoginServletTest:

  public class LoginServletTest extends TestCase {

  }

  我们首先测试当用户名和口令验证失败的情形,演示如何使用EasyMock来模拟HttpServletRequest对象:

  public void testLoginFailed() throws Exception {
  MockControl mc = MockControl.createControl(HttpServletRequest.class);
  HttpServletRequest request = (HttpServletRequest)mc.getMock();
  // set Mock Object behavior:
  request.getParameter("username");
  mc.setReturnValue("admin", 1);
  request.getParameter("password");
  mc.setReturnValue("1234", 1);
  // ok, all behaviors are set!
  mc.replay();
  // now start test:
  LoginServlet servlet = new LoginServlet();
  try {
  servlet.doPost(request, null);
  fail("Not caught exception!");
  }
  catch(RuntimeException re) {
  assertEquals("Login failed.", re.getMessage());
  }
  // verify:
  mc.verify();
  }

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号