2013-04-11 69 views
0

我有一個場景,就像我在代碼中動態創建i18n對象實例一樣。我正在使用下面的代碼:Mockito嘲笑任何創建運行時間的I18n實例

public String getLocaleString(Locale locale, SlingHttpServletRequest request){ 
    final ResourceBundle bundle = request.getResourceBundle(locale); 
    I18n i18n = new I18n(bundle); 
    return i18n.get("local"); 
} 

這裏locale,請求我嘲笑。但是i18n是動態創建的。所以我不能模擬i18n.get("local")

我試着使用:

when(any(I18n.class).get("local")).thenReturn("localizedString") 

但我不能。我在這一行中得到NullPointerException。

我想用Mockito來嘲笑這種情況。你們能幫我嗎?謝謝。

+0

當你調用'get'時,'I18n'會做什麼? – 2013-04-11 09:01:36

回答

2

已的Mockito建議重構來解決這個問題https://code.google.com/p/mockito/wiki/MockingObjectCreation?ts=1332544670&updated=MockingObjectCreation

我通常會避免的方法測試的內部。

但在某些情況下,當我真的需要我用PowerMockito https://code.google.com/p/powermock/wiki/MockConstructor

+0

是不測試內部的方法,它使測試變得脆弱!而是測試給定輸入的方法的結果行爲。還記得mock並不總是確保代碼正常工作的最佳選擇,有時使用真實對象進行測試是斷言代碼行爲的最佳方式。 – Brice 2013-04-11 09:22:09

1

我不認爲這是可能以這種方式使用any(),因爲它是一個參數匹配,你應該只用一種方法指定mock對象調用,例如:

when(mock(i18n).get("local")).thenReturn("localizedString"); 

我認爲這可能是您的NullPointerException的來源。

但要解決你的問題,我覺得你有兩個選擇:

第一種方法是使用一個工廠來創建I18n對象,然後嘲笑工廠:在

... 
private I18nFactory factory; 
... 

public String getLocaleString(Locale locale, SlingHttpServletRequest request){ 
    final ResourceBundle bundle = request.getResourceBundle(locale); 
    I18n i18n = factory.get(bundle); 
    return i18n.get("local"); 
} 

然後你試驗,建立了工廠生產所需的對象:

// Mock I18n, locale, request etc... 

final I18nFactory factory = mock(I18nFactory.class); 
when(factory.get(bundle)).thenReturn(i81n); 

// Assign 'factory' to your Controller(?) 
controller.setI18nFactory(factory); 

// act, assert etc... 

第二種方法是建立在localerequest MOC ks/objects以new I18n(...)創建一個符合您的期望的有效對象。

總而言之,我想我寧願使用第二種方法,尤其是如果I18n是第三方類。儘管沒有關於測試目標的更多信息,但這個答案有點推測。無論如何,我希望這有助於。

+0

嗨, 問題已解決。 主要問題是密鑰在ResourceBundle中不可用。 因此,我沒有給予模擬資源包,而是使用具有必要鍵和值的Resource對象創建了一個resourceBundle實例。之後,我將resourceBundle實例傳遞給該方法。 它的工作。非常感謝你的指導。 – 2013-04-16 11:30:28