如何模拟带有客户端或服务器错误的 RestTemplate?

问题描述 投票:0回答:3

我在代码中使用了

restTemplate.postForEntity()
。 在测试围绕它的类时,我使用 Mockito 来模拟 RestTemplate。

Mockito.when(restTemplate.postForEntity(.....)).thenReturn(response)

响应是:

ResponseEntity<String> response = new ResponseEntity(HttpStatus.UNAUTHORIZED);

现在,当我运行此测试时,

postForEntity
返回我刚刚显示的模拟响应。然而,在实际执行中,RestTemplate 在从远程接收到
RestClientException
时会抛出
401

在幕后,这是因为

doExecute()
中的
RestTemplate
检查错误并在出现 4XX 和 5XX 错误时抛出此异常。

我当然可以重写模拟规则:

Mockito.when(restTemplate.postForEntity(.....)).thenThrow(new RestClientException(..))
.

但是在阅读测试时,这不是很直观:我希望它本身响应 401 或 500。

我应该怎么做才能实现这个目标?

java spring mockito resttemplate
3个回答
3
投票

您已经在问题中说过:您正在嘲笑 RestTemplate 并测试使用它的类。你不是在嘲讽,只是在嘲笑。

如果您希望 RestTemplate 根据其接收到的 http 状态抛出该异常,那么您需要模拟 RestTemplate 使用的内部客户端,并使其在调用时返回该状态代码。然后你的 RestTemplate 应该被存根(或使用真正的实现)来对该 http 状态做出反应。

但在我看来这不是你想要测试的。

如果您只谈论测试的可读性(但继续测试您正在测试的内容),那么我建议创建一个基于http状态生成mockito答案的方法。如果状态不是 200 那么答案应该抛出异常。

所以,在你的resttemplate模拟中你会:

when(restTemplate.postForEntity(...))
    .thenAnswer(answer(401));

并回答实施类似:

private Answer answer(int httpStatus) {
    return (invocation) -> {
        if (httpStatus >= 400) {
            throw new RestClientException(...);
        }
        return <whatever>;
    };
}

这只是一个例子,您需要适应您的具体需求。


1
投票

您可以尝试使用Spring内置的测试库,如下所示:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/web/client/MockRestServiceServer.html

这样你就可以模拟你调用的端点


0
投票

我们可以这样模拟,这将返回 HttpClientErrorException ,错误代码为 401。

  when(restTemplate.postForEntity(url,new HttpEntity<>. 
         (authHeader()),String.class))
       .thenThrow(new HttpClientErrorException(HttpStatus. UNAUTHORIZED));
© www.soinside.com 2019 - 2024. All rights reserved.