团队
我的服务将作为独立程序运行,
我的代码:
public class TestRestTemplate {
private RestTemplate restTemplate;
public TestRestTemplate() {
restTemplate = new RestTemplate();
}
public void identifyInvoiceCategory(final Properties properties) throws Throwable {
final ResponseEntity<SearchResponse> exchange = restTemplate.exchange(
properties.getProperty("ENDPOINT"), HttpMethod.GET,
new HttpEntity<>(createSearchRequest(), createHttpHeader()), SearchResponse.class);
final SearchResponse searchResponse = exchange.getBody();
searchResponse.getEndIndex();
}
private SearchRequest createSearchRequest() throws Throwable {
final SearchRequest searchRequest = new SearchRequest();
return searchRequest;
}
private HttpHeaders createHttpHeader() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return httpHeaders;
}
}
我的 Junit 测试代码
@RunWith(MockitoJUnitRunner.class)
public class TestRest {
@Mock
private RestTemplate restTemplate;
@Test
public void testIdentifyInvoiceCategoryValid() throws Throwable {
try {
Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.eq(HttpMethod.GET),
ArgumentMatchers.any(), ArgumentMatchers.<Class<SearchResponse>>any())).thenReturn(null);
new TestRestTemplate().identifyInvoiceCategory(createProperties());
} catch (Throwable genThrowable) {
genThrowable.printStackTrace();
}
}
private Properties createProperties() {
final Properties properties = new Properties();
properties.setProperty("ENDPOINT", "http://www.test.com");
return properties;
}
}
当我运行 JUNIT 时,出现以下异常
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://www.test.com": Connection timed out: connect; nested exception is java.net.ConnectException: Connection timed out: connect
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:791)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:608)
at com.gxs.orch.aggregator.util.TestRestTemplate.identifyInvoiceCategory(TestRestTemplate.java:23)
看起来,它正在尝试连接到实际的 URL,而不是 Mocking...
你能帮我解决这个问题吗?
您嘲笑了
RestTemplate
,但在测试中您实际上没有将其注入到TestRestTemplate
中。因此,TestTestTemplate
正在使用您在构造函数中创建的RestTemplate
。
第一步是将您的模拟注入
TestRestTemplate
。最简单的方法是使用 @InjectMocks
注释:
@RunWith(MockitoJUnitRunner.class)
public class TestRest {
// Add this field:
@InjectMocks
private TestRestTemplate testRestTemplate;
@Mock
private RestTemplate restTemplate;
// ...
}
之后,您必须重构您的测试,以便它们使用 Mockito 创建的
TestRestTemplate
实例,而不是使用您自己的实例。这意味着无论您在哪里使用 new TestRestTemplate()
,您现在都指的是 testRestTemplate
字段。
例如:
@Test
public void testIdentifyInvoiceCategoryValid() throws Throwable {
// ...
// Don't use new TestRestTemplate():
testRestTemplate.identifyInvoiceCategory(createProperties());
// ...
}
此外,虽然
@InjectMocks
的工作并不是必需的,但在 RestTemplate
的构造函数中创建新的 TestRestTemplate
实例被认为是一种不好的做法,因为它会增加耦合。要解决此问题,您可以重构构造函数以接受外部 RestTemplate
实例:
public class TestRestTemplate {
private RestTemplate restTemplate;
// Refactor your constructor to this:
public TestRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
// ...
}