仅在测试子集中使用 MockRestServiceServer

问题描述

我想使用 MockRestServiceServer 测试来自我的服务的传出 HTTP 调用。我使用以下代码让它工作:

@SpringBoottest
class CommentFetcherTest {

@Autowired
RestTemplate restTemplate;

@Autowired
CommentFetcher commentFetcher;


@Test
public void shouldCallExternalService(){

    MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

    mockServer.expect(ExpectedCount.once(),requestTo("/test/endpoint")).andExpect(method(HttpMethod.GET));

    //when
    commentFetcher.fetchData();

    mockServer.verify();

}
}

然而,我遇到的问题是 RestTemplate 是套件中所有测试之间共享的 bean,这使得进一步运行应该调用外部服务的集成测试变得不可能。这导致:

java.lang.AssertionError: No further requests expected

如何仅将 MockRestServiceServer 用于测试子集? 我无法通过 @Autowired 摆脱依赖注入并在诸如

之类的测试中构建我的服务
RestTemplate restTemplate = new RestTemplate();
CommentFetcher commentFetcher = new CommentFetcher(restTemplate);

因为这不会从 application.properties 读取我的服务正常运行所必需的属性

解决方法

Spring Boot 提供了一种方便的方法来测试使用 Spring 的 RestTemplate@RestClientTest 的客户端类。

使用此注释,您将获得一个仅包含相关 bean 而不是您的整个应用程序上下文的 Spring 测试上下文(这是您当前使用 @SpringBootTest 获得的内容)。

MockRestServiceServer 也是此上下文的一部分,RestTemplate 配置为以它为目标。

基本测试设置如下所示:

@RestClientTest(CommentFetcher.class)
class UserClientTest {
 
  @Autowired
  private CommentFetcher userClient;
 
  @Autowired
  private MockRestServiceServer mockRestServiceServer;
 
  // ...
 
 
}

剩下的就是存根 HTTP 方法调用,然后在被测类上调用该方法(在您的情况下为 commentFetcher.fetchData();)。

如果您想详细了解如何使用 @RestClientTest 来测试您的 RestTemplate 使用情况,请参阅此 article