模拟方法中的依赖项而不是方法本身
Mocking a dependencies in a method instead of the method itself
我开发了一个 class,将我的应用程序与 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);
}
即使在我写它的时候,我也发现了它运行ge。我好像模拟根本不会调用原始方法中的任何代码。但是由于我是 mockito 的新手,所以我继续前进。在我 运行 声纳之后,我毫不奇怪地发现我的覆盖率下降了。我在同一件事上发现 this question,Jon Skeet 的回答一直都是正确的。我的问题是:如何只模拟依赖性,在我的例子中,来自 API?
的实际响应
阅读 link 中的问题,我意识到我唯一真正需要嘲笑的是以下内容:
final ResponseEntity<String> result = restTemplate.exchange(
properties.getUri().concat(key),
HttpMethod.GET,
entity,
String.class);
因为我不想实际调用端点,所以只测试整个方法。我该如何做到这一点?似乎很难,因为 result
是我要测试的方法中的一个变量。
你需要像下面这样模拟 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);
我开发了一个 class,将我的应用程序与 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);
}
即使在我写它的时候,我也发现了它运行ge。我好像模拟根本不会调用原始方法中的任何代码。但是由于我是 mockito 的新手,所以我继续前进。在我 运行 声纳之后,我毫不奇怪地发现我的覆盖率下降了。我在同一件事上发现 this question,Jon Skeet 的回答一直都是正确的。我的问题是:如何只模拟依赖性,在我的例子中,来自 API?
的实际响应阅读 link 中的问题,我意识到我唯一真正需要嘲笑的是以下内容:
final ResponseEntity<String> result = restTemplate.exchange(
properties.getUri().concat(key),
HttpMethod.GET,
entity,
String.class);
因为我不想实际调用端点,所以只测试整个方法。我该如何做到这一点?似乎很难,因为 result
是我要测试的方法中的一个变量。
你需要像下面这样模拟 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);