【问题标题】:How to mock the HttpServletRequest? [duplicate]如何模拟 HttpServletRequest? [复制]
【发布时间】:2012-10-08 09:28:54
【问题描述】:

我有一个查找查询参数并返回布尔值的函数:

  public static Boolean getBooleanFromRequest(HttpServletRequest request, String key) {
        Boolean keyValue = false;
        if(request.getParameter(key) != null) {
            String value = request.getParameter(key);
            if(keyValue == null) {
                keyValue = false;
            }
            else {
                if(value.equalsIgnoreCase("true") || value.equalsIgnoreCase("1")) {
                    keyValue = true;
                }
            }
        }
        return keyValue;
    }

我的 pom.xml 中有 junit 和 easymock,我该如何模拟 HttpServletRequest ?

【问题讨论】:

  • 下面回答这个问题写得很好,但我通常会主张重构代码,以便大多数非平凡的逻辑处于更合适的抽象级别。如果这是可能的,那么模拟 HttpServletRequest 就变得没有必要了。

标签: java junit easymock


【解决方案1】:

使用一些模拟框架,例如MockitoJMock 带有此类对象的模拟能力。

在 Mockito 中,您可以像这样进行模拟:

 HttpServletRequest  mockedRequest = Mockito.mock(HttpServletRequest.class);

有关 Mockito 的详细信息,请参阅:Mockito 网站上的How do I drink it?

在 JMock 中,您可以像这样进行模拟:

 Mockery context = new Mockery();
 HttpServletRequest  mockedRequest = context.mock(HttpServletRequest.class);

jMock详情请参考:jMock - Getting Started

【讨论】:

  • 因为它们使用具有类型推断的泛型,就像任何优秀的现代库一样。
  • 您将 .class 作为参数传递给模拟方法。
  • @Hiro2k - 这正是我所期望的,但我在网站上的示例中没有看到任何泛型...?
  • @RichardJPLeGuen docs.mockito.googlecode.com/hg/latest/org/mockito/… 看到方法签名中的泛型了吗?
  • @Hiro2k - 我想我只是混淆了 Java 和 C#。在 C# 中,泛型方法调用在 <> 方括号 (mock<HttpServletRequest>(...)) 中包含泛型,而在 Java 中看起来并非如此。
【解决方案2】:

HttpServletRequest 与任何其他接口很相似,因此您可以按照EasyMock Readme 模拟它

这是一个如何对 getBooleanFromRequest 方法进行单元测试的示例

// static import allows for more concise code (createMock etc.)
import static org.easymock.EasyMock.*;

// other imports omitted

public class MyServletMock
{
   @Test
   public void test1()
   {
      // Step 1 - create the mock object
      HttpServletRequest req = createMock(HttpServletRequest.class);

      // Step 2 - record the expected behavior

      // to test true, expect to be called with "param1" and if so return true
      // Note that the method under test calls getParameter twice (really
      // necessary?) so we must relax the restriction and program the mock
      // to allow this call either once or twice
      expect(req.getParameter("param1")).andReturn("true").times(1, 2);

      // program the mock to return false for param2
      expect(req.getParameter("param2")).andReturn("false").times(1, 2);

      // switch the mock to replay state
      replay(req);

      // now run the test.  The method will call getParameter twice
      Boolean bool1 = getBooleanFromRequest(req, "param1");
      assertTrue(bool1);
      Boolean bool2 = getBooleanFromRequest(req, "param2");
      assertFalse(bool2);

      // call one more time to watch test fail, just to liven things up
      // call was not programmed in the record phase so test blows up
      getBooleanFromRequest(req, "bogus");

   }
}

【讨论】:

    【解决方案3】:

    这是一个旧线程......但问题仍然相关。

    另一个不错的选择是Spring框架中的MockServiceRequest和MockServiceResponse:

    http://docs.spring.io/spring/docs/2.0.x/api/org/springframework/mock/web/package-summary.html

    【讨论】:

      【解决方案4】:

      我不知道easymock,但'Unit Testing in Java: How Tests Drive the Code' by Johannes Link 这本书解释了如何使用他构建的虚拟对象库来测试Servlet。

      这本书的配套网站现在已经消失了(出版公司的变化......)但是the companion site from the original german publication is still up。来自它,you can download the definitions of all the dummy objects

      【讨论】:

      • 发布者站点链接出现 404 错误。
      【解决方案5】:

      看看 Mockrunner:http://mockrunner.sourceforge.net/

      它有很多易于使用的 Java EE 模拟,包括 HttpServletRequest 和 HttpServletResponse。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多