![](/img/trans.png)
[英]Mock of RestTemplate in Junit test for mockRestTemplate.postForObject() return null
[英]Mocking RestTemplate#postForObject in a unit test
給定一個EncoderService
類,它具有以下createNewStream
方法和該方法中使用的一堆常量,如何使用mockito
為createNewStream
方法編寫單元測試:
public ResponseEntity<Object> createNewStream(Long channelId) {
String url = IP + VERSION + serverName + VHOSTS + vhostName + APP_NAME + appName + STREAM_FILES;
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.setAcceptCharset(Arrays.asList(Charset.forName(UTF_8)));
RestTemplate restTemplate = new RestTemplate();
String udp = "udp://" + "localhost" + ":" + "1935";
Map<String, String> map = new HashMap<>();
map.put("name", STREAMS + appName + channelId);
map.put("serverName", serverName);
map.put("uri", udp);
HttpEntity<Map<String, String>> request = new HttpEntity<>(map, headers);
HttpStatus statusCode = null;
try {
ResponseEntity<Object> response = restTemplate.postForEntity(url, request, Object.class);
statusCode = response.getStatusCode();
map.put(MESSAGE, "successful");
return new ResponseEntity<>(map, statusCode);
} catch (HttpStatusCodeException e) {
map.put(MESSAGE, e.getMessage());
return new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
}
}
RestTemplate
是一個類,而不是一個接口,它實現了實際的HTTP傳輸。 兩者都妨礙編寫可測試的方法。 最重要的是,您正在構造對OS級別具有副作用而不是注入它的類的實例並不能解決問題。 因此,解決方法是:
RestOperations
Supplier<RestOperations>
注入實現RestOperations
的實例,例如用於生產的RestTemplate
實例 Mockito.mock(RestOperations.class)
比較容易,因為像所有其他Spring接口一樣, RestOperations
定義了太多方法來手動編寫測試實現 因此,在EncoderService
您可以擁有:
private final RestOperations restClient;
public EncoderService(RestOperations restClient) {
this.restClient = restClient;
}
public ResponseEntity<Object> createNewStream(Long channelId) {
...
ResponseEntity<Object> response = restClient.postForEntity(...
...
}
然后在EncoderServiceTest
:
ResponseEntity<Object> expectedReturnValue = ...
RestOperations testClient = mock(RestOperations.class);
doReturn(expectedReturnValue).when(testClient).postForEntity(any(), any(), anyClass());
EncoderService service = new EncoderService(testClient);
// use the service
對於其他兩種情況,測試設置是完全相同的,只是您將實例傳遞給方法調用而不是構造函數,或覆蓋EncoderService
實例上的供應商以返回testClient
。
我已經回答了一個關於ProcessBuilder
的非常相似的問題,該問題在操作系統級別上也有副作用,並且是直接在此處測試的方法中構造的。嘗試使用PowerMockito模擬ProcessBuilder的構造函數時出錯您可以應用完全相同的策略。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.