Junit 断言失败的 HTTP post 请求

Junit Asserting failed HTTP post request

我的 spring 启动应用程序有一个 HTTPClient 测试。如果对服务器的 POST 请求是 2048 字节或以上的字符串,我有一个 class 会抛出异常。

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

    }


}

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

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

@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 响应失败)。

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

@Test 有一个参数断言抛出了一个特定的异常,你可以像这样编写你的测试:

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

您可以通过 3 种方式实现:

1) 在提供 class 要检查的异常的地方使用 @Test(expected = ....) 注释。

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

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

2) 使用 @Rule 注释和 ExpectedException class:

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

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

还有另一种解决方案,这些答案中没有提到,这是我个人的偏好。 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编辑器