2016-08-14 65 views
1

我想寫測試其他{ID = NULL JUnit測試用例中更改的方法值; }聲明在下面的代碼中。我想要做的是看看網站是否有活動,如果它是生成一個ID,但如果它不活(或下降了一點)返回id爲空。使用到的Mockito的方法

public static String createID() { 
    String id = null; 
    HttpURLConnection connection = accessProv(); 
    if (checkConfigs()) { 
     try { 
      if(checkSiteResponse(connection)) { 
       id = generateID(connection); 
      } else { 
       //test this statement 
       id = null; 
      } 
     } catch (IOException e) { 
      LOG.error("IOException"); 
     } 
    } else { 
     id = generateRandomID(); 
    } 
     return id; 
} 

public static boolean checkConfigs() { 
    return (stormConf != null && (boolean)stormConf.get(ENABLE_ID_REGISTRATION) && !((boolean)stormConf.get(SUBMIT_TOPOLOGY_LOCALLY))); 

public static HttpURLConnection accessProv() { 
    HttpURLConnection connection = null; 
    try { 
     URL url = new URL(PROV_CREATE_ID_URL); 
     connection = (HttpURLConnection) url.openConnection(); 
     connection.setRequestMethod("GET"); 
     connection.connect(); 
     int code = connection.getResponseCode(); 
    } catch (IOException e) { 
     LOG.error("IOException"); 
    } 
    return connection; 
} 
    public static boolean checkSiteResponse(HttpURLConnection connection) throws IOException { 
    Boolean response; 
    if (connection.getResponseCode() == 200) { 
     response = true; 
    } else { response = false; } 
    return response; 
} 

我寫了下面使用的的Mockito測試用例:

@Test 
public void testRequestError() throws ParseException, IOException { 
    HttpURLConnection mockHttpConnection = Mockito.mock(HttpURLConnection.class); 
    ProvenanceUtils provenanceUtils = Mockito.mock(ProvenanceUtils.class); 
    provenanceUtils.checkSiteResponse(mockHttpConnection); 
    when(provenanceUtils.checkConfigs()).thenReturn(true); 
    when(provenanceUtils.accessProvenance().getResponseCode()).thenReturn(100); 
    System.out.println(provenanceUtils.createID()); 

但我得到的錯誤:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Boolean cannot be returned by getResponseCode() 
getResponseCode() should return int 

我是新來的Mockito和無法弄清楚如何將getResponseCode設置爲200以外的內容。我在第一個語句(when(provenanceUtils.checkConfigs()).thenReturn(true);時收到錯誤。

基本上我想checkConfigs()返回true和checkSiteResponse(connection)返回false。有沒有辦法與Mockito做到這一點?我想避免使用PowerMock,如果我可以幫助它。

+1

嘲諷的HTTP請求,如果您正在測試'createID'你不應該嘲笑比'checkConfigs'和'checkSiteResponse'的任何其他。儘管這部分代碼不是必需的。我會重構它看起來更像這樣:https://gist.github.com/davelnewton/92b768d9925baa683e6323a4fd9f82cd –

回答

0

問題是,你將太多的責任推到一個班級。

實施例:你有一個靜態方法checkConfigs()。如果你想更換,與類似

interface ConfigurationChecker() { 
    boolean isConfigurationValid(); 
.. 

class ConfigurationCheckerImpl implements ... 

,然後,測試下你的類包含類型ConfigurationChecker的;並使用依賴注入(使你的單元測試可以推嘲笑 ConfigurationChecker到被測類)......突然間,你獲得完全控制在影響您的方法的行爲的元素。

換句話說:您的代碼,現在寫的就是來測試。所有你需要控制的元素;測試代碼根本不可(容易)訪問。

您可以使用Powermock/mockito來測試它,或者您退後一步,學習如何編寫易於測試的代碼(例如通過觀察this);重做你的設計......並最終得到A)更好的設計B)完全可測試(沒有「討厭」的解決方法)。

1

記住有了這樣的static methods can not be mocked with Mockito除非你用PowerMockito

除此之外,有什麼方法accessProvenance()的回報是不是模擬(是一個實際的HttpURLConnection實例),因此可以的Mockito不改變其行爲。

您可以嘗試使用WireMock

@Rule 
public WireMockRule wireMockRule = new WireMockRule(); 

... 
public void testRequestError() throws ParseException, IOException { 
    stubFor(post(urlEqualTo(PROV_CREATE_ID_URL)) 
    .willReturn(aResponse() 
     .withStatus(100))); 
... 
}