【问题标题】:Mocking a dependencies in a method instead of the method itself模拟方法中的依赖项而不是方法本身
【发布时间】:2021-05-20 14:41:40
【问题描述】:

我开发了一个将我的应用程序与 API 集成的类。当我第一次编写测试时,他们实际上正在运行它,但从长远来看,这会带来一些复杂性,所以我决定通过嘲笑我的沟通来重构测试。这是一种方法的片段,它是测试:

方法确认

public Response confirm(final String key) {
    final Response response;
    try {

        final HttpHeaders httpHeaders = this.initializeHeaders();
        final HttpEntity<String> entity = new HttpEntity<>(httpHeaders);
        final ResponseEntity<String> result = restTemplate.exchange(
                properties.getUri().concat(key),
                HttpMethod.GET,
                entity,
                String.class);

        response = this.handleResultJson(result);

    } catch (Exception e) {
        throw new IntegrationException(e.getMessage());
    }
    return response;
}

及其单元测试

@Test
void ShouldConfirm() {
    final Response response = new Response(
            true,
            UUID.randomUUID().toString(),
            "{\n" +
                    "    \"key\": \"dd227b53-550b-44a1-bb61-01016c3821ff\",\n" +
                    "    \"lastUpdated\": " + LocalDateTime.now() + ",\n" +
                    "}"
    );
    when(service.confirm(KEY)).thenReturn(response);
    assertEquals(service.confirm(KEY), response);
}

即使在我写它的时候,我也觉得它很奇怪。我似乎根本不会从原始方法中调用任何代码。但由于我是 mockito 的新手,所以我继续前进。在我运行声纳之后,毫不奇怪,我发现我的覆盖率下降了很多。我在同一件事上发现了this question,而 Jon Skeet 的答案一直都是正确的。我的问题是:我如何只模拟依赖,在我的情况下,API 的实际响应?

阅读链接中的问题后,我意识到我真正需要嘲笑的是以下内容:

final ResponseEntity<String> result = restTemplate.exchange(
                properties.getUri().concat(key),
                HttpMethod.GET,
                entity,
                String.class);

因为我不想实际调用端点,所以只测试整个方法。我该如何做到这一点?似乎很困难,因为result 是我要测试的方法中的一个变量。

【问题讨论】:

标签: java spring mockito junit5


【解决方案1】:

你需要像下面这样模拟resttemplate

@Mock
private RestTemplate restTemplate ;

restTemplate.exchange()

ResponseEntity<String> responseEntity = new ResponseEntity<String>("sampleBodyString",HttpStatus.OK);

when(restTemplate.exchange(
                           Matchers.anyString(), 
                           Matchers.any(HttpMethod.class),
                           Matchers.<HttpEntity<?>> any(), 
                           Matchers.<Class<String>> any()
                          )
                         ).thenReturn(responseEntity);

【讨论】:

  • 这正是我所需要的。如何使确认方法仅在从单元测试运行时获取模拟的 responseEntity?
  • “仅在从单元测试用例运行时”是什么意思?
  • 作为替代方案,您可以使用MockRestServiceServer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多