Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用url字符串创建模拟HttpServletRequest?_Java_Mocking_Servlets - Fatal编程技术网

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

Java 用url字符串创建模拟HttpServletRequest?,java,mocking,servlets,Java,Mocking,Servlets,我有一个服务在HttpServletRequest对象上执行一些工作,特别是使用request.getParameterMap和request.getParameter来构造一个对象 我想知道是否有一种简单的方法可以获取提供的url,比如字符串形式 String url = "http://www.example.com/?param1=value1&param"; 并轻松地将其转换为HttpServletRequest对象,以便使用单元测试对其进行测试?或者至少让request.ge

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

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

String url = "http://www.example.com/?param1=value1&param";
并轻松地将其转换为HttpServletRequest对象,以便使用单元测试对其进行测试?或者至少让request.getParameterMap和request.getParameter正常工作?

Spring的Spring测试模块中有


如果您使用的是maven,则可能需要将适当的依赖项添加到pom.xml。您可以在找到SpringTest。

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


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

模拟
HttpServletRequest的最简单方法是:

  • 创建一个匿名子类:

    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
    };
    
  • 使用HttpUnit,不要模仿请求


  • 下面介绍如何使用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"));
    

    对于那些想用Json有效负载模拟
    POST
    HttpServletRequest的人来说,下面是Kotlin中的内容,但这里的关键是当你想模拟
    请求时的。从
    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)
    }
    

    再说一次,为什么仅仅因为方法采用了某种类型的参数作为输入,就错过了增加测试覆盖率(即代码健壮性)的机会?这取决于,您是在尝试对servlet API进行单元测试,还是在尝试对自己的代码进行单元测试?“一般而言”您不希望在servlet方法中包含任何代码。实际上,你永远都会。您将拥有帮助器类、实用程序方法、解析、验证、模型转换,有时甚至还有业务逻辑(可怕!)。既然您这样做了,您就需要对它们进行单元测试。因此,您需要模拟servlet请求来创建定义良好的测试场景。模拟ServletAPI与测试它恰恰相反。它将从测试用例中完全删除它。使用这个MockHttpServletRequest实际上完成了这项工作,因为我只需要一个功能完整的HttpServletRequest注意,当设置queryString时,参数映射不会在MockHttpServletRequest中自动更新。因此,如果在代码中使用request.getParameter(),则必须先在测试设置中显式设置它,即使它一开始看起来可能是多余的。我注意到了同样的情况。查询字符串和参数似乎不同步upjee api jar 6或8将需要进行此操作。注释中的内容是什么?
    @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)
    }