[英]how to junit test on restTemplate?
我在用 Mockito 模擬 restTemplate 時遇到問題
代碼要測試:
public class Feature{
public static String getfeature(String url){
RestTemplate restTemplate = new RestTemplate();
String xml = "\"feature\": 1";
String json = restTemplate.postForObject(url, xml, String.class);
return json;
}
}
聯合代碼:
@Mock
RestTemplate restTemplate=mock(RestTemplate.class);
@Test
public void testGetfeature(){
string testResponse= "\"feature\": 1";
Mockito.when((String)restTemplate.postForObject(
Mockito.any(String.class),
Mockito.any(Map.class),
Mockito.any(Class.class)
)).thenReturn(testResponse);
Feature feature = new Feature();
feature.getfeature("http://mockValue");
}
我在 feature.getfeature(" http://mockValue ") 設置斷點。 它仍然嘗試連接到遠程服務器。 我不希望 postForObject 連接到http://mockValue 。 我應該如何模擬 restTemplate 使 postForObject 不連接到http://mockValue ?
您正在使用getfeature()
方法創建一個新的RestTemplate
對象。 因此,嘲笑RestTemplate
無效。 將RestTemplate
用作getfeature()
方法中的參數,或者將其用作Feature
類中的構造函數參數。
然后從測試類中,您可以模擬RestTemplate並像下面那樣傳遞它:
Feature feature= new Feature(mockRestTemplate);
feature.getfeature(url);
要么
Feature feature = new Feature();
feature.getfeature(mockRestTemplate, url);
您必須根據決策在Feature類中進行必要的更改。
這是運行代碼示例:
主班:
public class Feature {
public static String getFeature(String url, RestTemplate restTemplate) {
return restTemplate.postForObject(url, "", String.class);
}
}
測試類別:
請注意RestTemplate
的方式,然后RestTemplate
響應的方式。
public class FeatureTest {
@Test
public void testFeature() {
RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
Mockito.when(restTemplate.postForObject(Mockito.any(String.class),
Mockito.any(Object.class), Mockito.any(Class.class))).thenReturn("abc");
System.out.println(Feature.getFeature("http://abc", restTemplate));
}
}
github上也提供了運行代碼示例
無需不斷創建RestTemplate對象。
您可以創建一個並將其注入到類中。
然后,在單元測試中,創建一個模擬RestTemplate並將其注入。
編輯:
關於靜態方法。 不要使用靜態方法,這很糟糕。 如果您使用的是Spring(或其他任何依賴注入框架),則只需在要進行其余調用的地方注入Feature
的實例。
另外,在春季世界中, Feature
是服務類。 使用@Service批注並使該方法不是靜態的。
我認為您需要更改代碼以使單元測試至少可以使用Mockito進行工作,或者必須使用Powermock等其他庫來模擬本地對象實例化。
1)創建一個接受RestTemplate作為參數的構造函數,以注入您的模擬。
要么
2)創建一些setter方法來注入RestTemplate。
還有一種方法是創建可以傳遞RestTemplate的另一種方法。
public String getStringAsJson(RestTemplate restTemplate, String url, String xml) {
return restTemplate.postForObject(url, xml, String.class);
}
然后在您的測試中:
RestTemplate mockRestTemplate = mock(RestTemplate.class);
when(restTemplate.postForObject(mockurl, mockUrl, mockXml)).thenReturn("Json");
feature.getStringAsJson(mockRestTemplate,mockUrl,mockXml);
如何在restTemplate上進行junit測試?
我們測試它返回什么。
當前,您的實現本身不執行任何操作,它僅委托給RestTemplate
並返回其結果。
fiveelements
答案描述了實現(以廣泛接受的值作為參數):
@Test
public void testFeature() {
RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
Mockito.when(restTemplate.postForObject(Mockito.any(String.class),
Mockito.any(Object.class), Mockito.any(Class.class))).thenReturn("abc");
System.out.println(Feature.getFeature("http://abc", restTemplate));
}
但這並不能斷言實際的行為:URL可能是錯誤的,正文或響應可能是錯誤的,因此……此測試將永遠不會檢測到該行為。 最后,在此實現中非常重要的事情可能是錯誤的,我們無法檢測到。 這種測試的價值太弱了。
由於此方法本身並不執行邏輯,因此它更適合於可以在實際行為中斷言並捕獲更多事物/問題的集成測試:
@Test
public void testFeature() {
String actualFeature = Feature.getFeature("http://...");
String expectedFeature = ...;
Assertions.assertEquals(expectedFeature, actualFeature);
}
如果您使用PowerMockito ,那么您可以執行以下操作:
Feature 類在這里不需要更改代碼,如果 prj 中有 PowerMockito lib,您可以直接使用它
RestTemplate mockedRestTemplate = PowerMockito.mock(RestTemplate.class);
PowerMockito.whenNew(RestTemplate.class).withAnyArguments().thenReturn(mockedRestTemplate);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.