【问题标题】:Junit Asserting failed HTTP post requestJunit断言失败的HTTP post请求
【发布时间】:2019-08-12 14:45:06
【问题描述】:

我的 Spring Boot 应用程序有一个 HTTPClient 测试。如果对服务器的 POST 请求在 2048 字节或以上的字符串中,我有一个类会引发异常。

@Component
 public class ApplicationRequestSizeLimitFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
        System.out.println(request.getContentLength());
        if (request.getContentLengthLong() >= 2048) {
            throw new IOException("Request content exceeded limit of 2048 bytes");
        }
        filterChain.doFilter(request, response);

    }


}

我为它创建了一个单元测试,但我不确定如何编写断言语句来检查它是否无法发布请求。

到目前为止,我的测试课中有这个

@Test
    public void testSize() throws ClientProtocolException, IOException {
        Random r = new Random(123);
        long start = System.currentTimeMillis();
        String s = "";
        for (int i = 0; i < 65536; i++)
            s += r.nextInt(2);
        String result = Request.Post(mockAddress)
                .connectTimeout(2000)
                .socketTimeout(2000)
                .bodyString(s, ContentType.TEXT_PLAIN)
                .execute().returnContent().asString();

    }

此测试失败,这是我想要的,但我想创建一个断言以便它通过(断言它由于超过字节限制而导致 http 响应失败)。

【问题讨论】:

  • 你有异常吗? @Test 有一个参数来断言抛出了异常,例如 @Test(expected = IOException.class)
  • 是的,它应该给出错误消息的异常。这行得通,谢谢。请写下这个答案,以便我接受并给你积分。

标签: java spring-boot http junit assert


【解决方案1】:

您可以用 try/catch 包围失败的部分,并在 try 块的末尾调用 fail()。如果抛出异常,则不应到达 fail() 指令,并且您的测试应该通过。

【讨论】:

  • 我更喜欢这种方法,因为您可以检查异常本身以确保它包含您可能期望的失败消息。
【解决方案2】:

@Test 有一个参数来断言某个特定的异常被抛出,你可以编写你的测试,例如:

    @Test(expected = IOException.class)
    public void testSize() throws ClientProtocolException, IOException {
    ...
    }

【讨论】:

    【解决方案3】:

    有 3 种方法可以实现:

    1) 使用@Test(expected = ....) 注释来提供要检查的异常类别。

    @Test(expected = IOException.class)
    public void test() {
      //... your test logic
    }
    

    这不是推荐的异常测试方法,除非你的测试真的很小并且只做一件事。否则,您可能会收到 IOException 抛出,但您无法确定究竟是哪部分测试代码导致了它。

    2) 将@Rule 注释与ExpectedException 类一起使用:

    @Rule
    public ExpectedException exceptionRule = ExpectedException.none();
    
    @Test
    public void testExpectedException() {
        exceptionRule.expect(IOException.class);
        exceptionRule.expectMessage("Request too big.");
    //... rest of your test logic here
    }
    

    请注意exceptionRule 必须是public

    3) 最后一个,非常老式的方式:

    @Test
    public void test() {
      try {
        // your test logic
        fail(); // if we get to that point it means that exception was not thrown, therefore test should fail.
      } catch (IOException e) {
        // if we get here, test is successfull and code seems to be ok.
      }
    }
    

    这是一种老式的方法,会在您的测试中添加一些本应是干净的不必要的代码。

    【讨论】:

      【解决方案4】:

      还有另一种解决方案,这些答案中尚未提出,这是我个人的偏好。 assertThatThrownBy

      在你的情况下

      @Test
      public void testSizeException(){
        assertThatThrownBy(()-> Request.Post(mockAddress)
                        .connectTimeout(2000)
                        .socketTimeout(2000)
                        .bodyString(s, ContentType.TEXT_PLAIN)
                        .execute().returnContent().asString())
                        .isInstanceOf(IOException.class)
                        .hasMessageContaining("Request content exceeded limit of 2048 
        bytes");
      }
      

      *免责声明,以上代码直接写入SO编辑器

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-08
        • 1970-01-01
        • 2021-10-20
        相关资源
        最近更新 更多