如何模拟HttpServletRequest?

39
我有一个函数,它查找一个查询参数并返回布尔值:
  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进行mock处理?


3
以下回答这个问题写得很好,但我通常主张重构代码,使大部分非平凡逻辑在更合适的抽象级别上。如果可能的话,模拟HttpServletRequest就变得不必要了。 - James Kingsbery
5个回答

28

使用一些模拟框架,例如 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 - 入门指南


因为它们使用了泛型和类型推断,就像任何好的现代库应该做的那样。 - Hiro2k
1
你正在将 .class 作为参数传递给模拟方法。 - Yogendra Singh
@Hiro2k - 这是我所期望的,但我在网站示例中没有看到任何泛型...? - Richard JP Le Guen
@RichardJPLeGuen http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#mock(java.lang.Class) 看到方法签名中的泛型了吗? - Hiro2k
@Hiro2k - 我觉得我只是混淆了Java和C#。在C#中,泛型方法调用包括在<>括号中的泛型(mock<HttpServletRequest>(...)),而在Java中似乎不是这种情况。 - Richard JP Le Guen

15

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");

   }
}

11

2

发布者网站链接出现404错误。 - JohnK

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接