从url字符串创建模拟HttpServletRequest?

时间:2011-06-23 14:06:14

标签: java mocking servlets

我有一个服务在HttpServletRequest对象上做了一些工作,特别是使用request.getParameterMap和request.getParameter来构造一个对象。

我想知道是否有一种直接的方式来获取提供的网址,以字符串的形式,说

String url = "http://www.example.com/?param1=value1&param";

并轻松将其转换为HttpServletRequest对象,以便我可以使用单元测试对其进行测试?或者至少只是为了让request.getParameterMap和request.getParameter正常工作?

5 个答案:

答案 0 :(得分:38)

模仿HttpServletRequest的最简单方法:

  1. 创建一个匿名子类:

    HttpServletRequest mock = new HttpServletRequest ()
    {
        private final Map<String, String[]> params = /* whatever */
    
        public Map<String, String[]> getParameterMap()
        {
            return params;
        }
    
        public String getParameter(String name)
        {
            String[] matches = params.get(name);
            if (matches == null || matches.length == 0) return null;
            return matches[0];
        }
    
        // TODO *many* methods to implement here
    };
    
  2. 使用jMockMockito或其他一些通用模拟框架:

    HttpServletRequest mock = context.mock(HttpServletRequest.class); // jMock
    HttpServletRequest mock2 = Mockito.mock(HttpServletRequest.class); // Mockito
    
  3. 使用HttpUnit的ServletUnit并且根本不会模拟请求。

答案 1 :(得分:37)

Spring在其弹簧测试模块中有MockHttpServletRequest

如果您使用的是maven,则可能需要在 pom.xml 中添加适当的依赖项。你可以在mvnrepository.com找到弹簧测试。

答案 2 :(得分:31)

这是如何使用MockHttpServletRequest:

// given
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServerName("www.example.com");
request.setRequestURI("/foo");
request.setQueryString("param1=value1&param");

// when
String url = request.getRequestURL() + '?' + request.getQueryString(); // assuming there is always queryString.

// then
assertThat(url, is("http://www.example.com:80/foo?param1=value1&param"));

答案 3 :(得分:3)

您通常会在集成测试中测试这些类型的东西,它实际上连接到服务。要进行单元测试,您应该测试servlet的doGet / doPost方法使用的对象。

通常,您不希望在servlet方法中有太多代码,您可能希望创建一个bean类来处理操作并将自己的对象传递给它而不是servlet API对象。

答案 4 :(得分:1)

对于那些寻求使用Json有效负载模拟POST HttpServletRequest的用户,下面是Kotlin,但是这里要摘录的关键是 DelegatingServetInputStream request.getInputStream

模拟HttpServletRequest
@Mock
private lateinit var request: HttpServletRequest

@Mock
private lateinit var response: HttpServletResponse

@Mock
private lateinit var chain: FilterChain

@InjectMocks
private lateinit var filter: ValidationFilter


@Test
fun `continue filter chain with valid json payload`() {
    val payload = """{
      "firstName":"aB",
      "middleName":"asdadsa",
      "lastName":"asdsada",
      "dob":null,
      "gender":"male"
    }""".trimMargin()

    whenever(request.requestURL).
        thenReturn(StringBuffer("/profile/personal-details"))
    whenever(request.method).
        thenReturn("PUT")
    whenever(request.inputStream).
        thenReturn(DelegatingServletInputStream(ByteArrayInputStream(payload.toByteArray())))

    filter.doFilter(request, response, chain)

    verify(chain).doFilter(request, response)
}