簡體   English   中英

如何在 restTemplate 上進行 junit 測試?

[英]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上也提供了運行代碼示例

Feature.javaFeatureTest.java

無需不斷創建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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM