如何模拟 RestTemplate 的新实例?

How to mock new instance of RestTemplate?

我正在为遗留代码编写单元测试,类似于:

public class SomeClass {
public SomeResponse logToServer() {
    SomeResponse response = null;
    try{ 
        RestTemplate restTemplate = new RestTemplate();
        SomeRequestBean request = new SomeRequestBean();
        response = restTemplate.postForEntity("http://someUrl", request, SomeResponse.class);
        System.out.println(response.toString());
    } catch(Exception e) {
        e.printStackTrace();
    } 
    return response;
}

}

我知道我可以将 RestTemplate 移到上面并将其注释为 @AutoWire 并将其声明为 bean class 或使用 power mockito 来模拟新实例的创建。但是我不想更改这个遗留代码,并且我不惜一切代价避免使用强大的 Mockito,因为只是为了一个测试,我不想向我的 pom.xml 添加一个全新的依赖项。所以只是想知道有什么方法可以用来模拟这个 restTemplate 吗?

回答你的问题,根据你发布的限制,没有办法模拟 RestTemplate 和单元测试它。

我确实认为您可以稍微更改遗留代码,因为此更改不起作用,在这种情况下可能值得。但我会坚持你做不到的。

关于 power mock 和 power mockito。虽然我同意应该避免使用这些工具,但不是出于您发布的原因。请注意,此依赖项属于测试范围,即使对于遗留环境,它也不会影响生产。所以如果优先考虑的是不改变遗留代码,那么引入PowerMock就是"least evil".

如果我们专门讨论 rest 模板,您可以利用一些关于 spring rest 模板的事实,这些事实可用于测试它。

选项 1

第一种技术(如果环境允许)是使用@RestClientTest注解。它将允许指定被测服务,并将提供一个名为 MockRestServiceServer 的模拟实现,它将代表您在模拟环境中尝试连接的服务器。然后您将能够指定对此服务器的期望,希望代码将 运行。注意:这不是单元测试 - 这是启动 spring 上下文的集成测试,因此它比常规单元测试 heavier/slower 多。

Here 您可以找到这种方法的工作示例,查看这篇文章,它还包含其他技术。

选项 2

第二种技术背后的想法是 RestTemplate 实际上是客户端库之上的包装器,它本身不进行任何 http 相互通信。

它可以配置为与apache的HttpClient OkHttpClient一起工作,默认情况下它与URLConnection一起工作,为每个请求打开连接。因此,您可以创建一个测试,将其余客户端配置为 运行 使用 interest/choice 的某些特定引擎,然后查看如何测试直接使用该引擎的代码。根据项目中实际使用的引擎,解决方案会有所不同。