【问题标题】:test chained REST API's in spring boot在 Spring Boot 中测试链式 REST API
【发布时间】:2019-08-24 23:42:37
【问题描述】:

在我的RestController 中模拟外部 API 调用的正确方法是什么。 意思是我的RestController 实际上做了这些步骤:

  1. 转换日期
  2. 用数据调用外部 API
  3. 使用外部 API 响应进行响应

由于安全问题无法复制/粘贴,但一般来说:

@RestController
public Class x{
RestTemplate y = new RestTemplate();

@RequestMapping(value="/someurl" , method=RequestMethod=POST)
public String myMethod(@RequestBody JsonNode myjson)
{
  //business logic
  ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod,
                                          internalRequest,String.class);
  return response.getBody()
}

【问题讨论】:

  • 显示调用外部 API 的类的(代码/示例)
  • 但是对外部 API 的调用是在不同的类/方法中吗?方法是怎么调用的?
  • 上面添加了代码示例
  • 您是否只进行了一次外部 API 调用?
  • @Deadpool - 是的

标签: spring-boot spring-test spring-boot-test spring-test-mvc


【解决方案1】:

在这里,您正在创建一个新的 RestTemplate 实例。您可以考虑在 Configuration 类中定义一个 RestTemplate 的 bean,并在此处自动装配它以使用 Mockito 框架对其进行模拟和测试。

那么控制器中的代码必须如下所示。

@RestController
public Class Controller{

   @Autowired
   RestTemplate restTemplate;

RestTemplate bean 应该在配置类中定义如下

@Configuration
public class Config {

  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
  }
} 

完成上述操作后,您可以如下模拟 RestTemplate

@RunWith(MockitoJUnitRunner.class)
public class ControllerTest {

  @Mock
  RestTemplate restTemplate;

  @InjectMocks
  Controller controller;

  @Test
  public void myMethodTest() {
     Mockito.when(restTemplate.exchange(Mockito.eq(your url), 
                 Mockito.eq(HttpMethod.your method), Mockito.<HttpEntity<your request 
                 class>> any(), Mockito.<Class<your response class>> 
                 any())).thenReturn(your response entity);
     String response = controller.myMethod(your request);
     Assert.assertThat(response, CoreMatchers.is((your response entity).getBody));
  }

使用上述方法,您可以断言来自模拟的 restTemplate 的响应。

【讨论】:

  • 我有两个问题 - 一个是:@Autowired RestTemplate restTemplate;有一个错误:“无法自动装配。没有'RestTemplate'的bean ...”另一个是如何按照您描述的方式调用myController.myMethod,因为它是REST API,而不是常规方法。以及它将如何工作,mockito 正在使用我在 Mockito.when()... 行中给它的返回值更改我的 API 中间的外部调用?
  • 您是否在 @Configuration 类中定义了 RestTemplate bean?您可以调用 myController.myMethod 因为 myController 通过注入 RestTemplate 模拟来模拟。当调用“myMethod”时,将调用模拟的restTemplate,您将收到您在“thenReturn”中返回的输出
【解决方案2】:

我一直使用Wiremock 在我的集成测试中进行更复杂的存根。

这是一个库,您可以将其添加为依赖项,并让您在测试上下文中存根任何指定的端点(甚至是外部端点)。

项目文档中的示例存根:

stubFor(get(urlEqualTo("/my/resource"))
            .withHeader("Accept", equalTo("text/xml"))
            .willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "text/xml")
                .withBody("<response>Some content</response>")));

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 2017-04-23
    • 2017-11-02
    • 1970-01-01
    • 2019-07-18
    • 2016-11-28
    • 2019-05-26
    • 2022-01-25
    • 2016-11-30
    相关资源
    最近更新 更多