MockRestServiceServer:如何用身体模拟 POST 调用?

Posted

技术标签:

【中文标题】MockRestServiceServer:如何用身体模拟 POST 调用?【英文标题】:MockRestServiceServer: how to mock a POST call with a body? 【发布时间】:2019-12-11 04:57:58 【问题描述】:

我正在尝试通过以下方式使用MockRestServiceServer 模拟 POST 方法:

MockRestServiceServer server = bindTo(restTemplate).build();
server.expect(requestTo("/my-api"))
        .andExpect(method(POST))
        .andRespond(withSuccess(expectedResponce, APPLICATION_JSON));

问题:如何在此设置中验证请求正文?

我浏览了the documentation 和一些示例,但仍然无法弄清楚它是如何完成的。

【问题讨论】:

为什么要检查请求正文?这是输入数据,不应验证。只是拼写错误,您的意思是响应正文吗? @IgorKhvostenkov 这是一个 POST 请求,这意味着它发送一条数据。我想验证发送的信息是否正确。 我不认为你做对了,如果你正在尝试验证请求正文,你只需要测试你是如何创建正文的,而不是模拟 Api 并测试你发送的内容那里... 无论是 GET 还是 POST,这都无关紧要。从概念上讲,测试您手动定义为正确或错误但不是由生产代码决定的东西是很奇怪的。您可以使用@user7294900 提出的方法,但更多的是缩小模拟范围或更精确的触发器,而不是验证您的生产代码。 @IgorKhvostenkov 也许“验证”在这里不是最好的词。让我详细说明。我正在编写集成测试。我不想从测试中获得真正的 API,而是在模拟 API。但如果我不检查请求正文,模拟 API 将为所有请求返回成功响应,这是我不想要的。 【参考方案1】:

你可以使用content().string来验证body:

.andExpect(content().string(expectedContent))

或content().bytes:

this.mockServer.expect(content().bytes("foo".getBytes()))

this.mockServer.expect(content().string("foo"))

【讨论】:

【参考方案2】:

我会怎么做这样的测试。我希望在模拟服务器上以String 格式接收正确的正文,如果已收到此正文,服务器将以String 格式的正确响应正文进行响应。当我收到响应正文时,我会将其映射到 POJO 并检查所有字段。另外,我会在发送之前将来自String 的请求映射到 POJO。所以现在我们可以检查映射是否在两个方向上工作,我们可以发送请求并解析响应。代码是这样的:

  @Test
  public void test() throws Exception
    RestTemplate restTemplate = new RestTemplate();
    URL testRequestFileUrl = this.getClass().getClassLoader().getResource("post_request.json");
    URL testResponseFileUrl = this.getClass().getClassLoader().getResource("post_response.json");
    byte[] requestJson = Files.readAllBytes(Paths.get(Objects.requireNonNull(testRequestFileUrl).toURI()));
    byte[] responseJson = Files.readAllBytes(Paths.get(Objects.requireNonNull(testResponseFileUrl).toURI()));
    MockRestServiceServer server = bindTo(restTemplate).build();
    server.expect(requestTo("http://localhost/my-api"))
          .andExpect(method(POST))
          .andExpect(content().json(new String(requestJson, "UTF-8")))
          .andRespond(withSuccess(responseJson, APPLICATION_JSON));

    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl("http://localhost/my-api");

    ObjectMapper objectMapper = new ObjectMapper();
    EntityOfTheRequest body = objectMapper.readValue(requestJson, EntityOfTheRequest.class);

    RequestEntity.BodyBuilder bodyBuilder = RequestEntity.method(HttpMethod.POST, uriBuilder.build().toUri());
    bodyBuilder.accept(MediaType.APPLICATION_JSON);
    bodyBuilder.contentType(MediaType.APPLICATION_JSON);
    RequestEntity<EntityOfTheRequest> requestEntity = bodyBuilder.body(body);

    ResponseEntity<EntityOfTheResponse> responseEntity = restTemplate.exchange(requestEntity, new ParameterizedTypeReference<EntityOfTheResponse>() );
    assertThat(responseEntity.getBody().getProperty1(), is(""));
    assertThat(responseEntity.getBody().getProperty2(), is(""));
    assertThat(responseEntity.getBody().getProperty3(), is(""));
  

【讨论】:

【参考方案3】:

可能使用 HttpMessageConverter 可以提供帮助。 根据document,HttpMessageConverter::read 方法可以是提供检查输入能力的地方。

【讨论】:

以上是关于MockRestServiceServer:如何用身体模拟 POST 调用?的主要内容,如果未能解决你的问题,请参考以下文章

使用 MockRestServiceServer 时无法精确测试服务调用次数

如何在 MockRestServiceServer 中通过字符串模式期待 requestTo?

Spring MockRestServiceServer 处理多个异步请求

由于未绑定的 RestTemplate,Spring-Boot RestClientTest 无法正确自动配置 MockRestServiceServer

如何用OpenLayers画扇形

如何用excel做散点图(如何用excel做柱状图)