Java 从 url 字符串创建模拟 HttpServletRequest?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6455359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:06:53  来源:igfitidea点击:

Creating a mock HttpServletRequest out of a url string?

javamockingservlets

提问by Anthony

I have a service that does some work on an HttpServletRequest object, specifically using the request.getParameterMap and request.getParameter to construct an object.

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

I was wondering if there is a straightforward way to take a provided url, in the form of a string, say

我想知道是否有一种直接的方法来获取提供的 url,以字符串的形式,比如

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

and easily convert it to a HttpServletRequest object so that I can test it with my unit tests? Or at least just so that request.getParameterMap and request.getParameter work correctly?

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

采纳答案by pap

Spring has MockHttpServletRequestin its spring-test module.

Spring在其 spring-test 模块中有MockHttpServletRequest

If you are using maven you may need to add the appropriate dependency to your pom.xml. You can find spring-test at mvnrepository.com.

如果您使用的是 maven,您可能需要向pom.xml添加适当的依赖项。您可以在mvnrepository.com 上找到 spring-test 。

回答by Triton Man

You would generally test these sorts of things in an integration test, which actually connects to a service. To do a unit test, you should test the objects used by your servlet's doGet/doPost methods.

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

In general you don't want to have much code in your servlet methods, you would want to create a bean class to handle operations and pass your own objects to it and not servlet API objects.

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

回答by Matt Ball

Simplest ways to mock an HttpServletRequest:

模拟 的最简单方法HttpServletRequest

  1. Create an anonymous subclass:

    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. Use jMock, Mockito, or some other general-purpose mocking framework:

    HttpServletRequest mock = context.mock(HttpServletRequest.class); // jMock
    HttpServletRequest mock2 = Mockito.mock(HttpServletRequest.class); // Mockito
    
  3. Use HttpUnit's ServletUnitand don't mock the request at all.

  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并且根本不要模拟请求。

回答by Guito

Here it is how to use MockHttpServletRequest:

下面是 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"));

回答by mel3kings

for those looking for a way to mock POSTHttpServletRequest with Json payload, the below is in Kotlin, but the key take away here is the DelegatingServetInputStreamwhen you want to mock the request.getInputStreamfrom the HttpServletRequest

对于那些正在寻找一种POST使用 Json 有效负载模拟HttpServletRequest的方法的人来说,下面是 Kotlin 中的,但这里的关键是DelegatingServetInputStream当您想request.getInputStreamHttpServletRequest

@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)
}