2012-08-23 116 views
6

我試圖嘲笑最後的方法ResourceBundle.getString()。使用PowerMock 1.4.12和EasyMock 3.1,通話不會被模擬;相反,「真正的」方法被調用。用PowerMock + EasyMock嘲笑最後的方法

我的測試類:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ResourceBundle.class) 
public class TestSuite { 
    @Before 
    public void setUp() throws Exception { 
     ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class); 
     expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue"); 
     PowerMock.replay(resourceBundleMock); 

     beanBeingTested.setMessages(resourceBundleMock); 
    } 
    ... 
} 

代碼在BeanBeingTested:

private ResourceBundle messages; 
... 
String label = messages.getString(BundleConstants.QUEUE); 

錯誤消息:

java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue 
at java.util.ResourceBundle.getObject(ResourceBundle.java:384) 
at java.util.ResourceBundle.getString(ResourceBundle.java:344) 
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87) 

當我通過測試情況下,步驟,調試器顯示的類型beanBeingTested.messages作爲「EasyMock for class java.util.ResourceBundle」,所以模擬注入corr ectly。 (另外,在設置期間呼叫expect()呼叫getString()時沒有錯誤)。

如果是單純的模仿,而不是一個很好的模擬,我得到以下錯誤:

java.lang.AssertionError: 
    Unexpected method call handleGetObject("Queue"): 
    getString("Queue"): expected: 1, actual: 0 

任何想法,我做錯了嗎?

謝謝。

回答

0

爲什麼要嘲笑對資源包的調用?一般來說,我儘量避免嘲笑java的各種細節,比如ArrayList,Date等等。資源包(和MessageFormat.format())或多或少屬於我的相同類別。他們通常在基本原則上操作字符串,如果這些東西被打破或改變他們的行爲足以打破測試,這絕對是我想知道的東西:)

只要讓他們搶字符串(這大概是要因爲你不想編輯這個包來破壞你的測試,所以不要打斷你返回的值。如果字符串被設置在一個模擬UI組件上,這對anyObject來說是個好地方(String.class),它正確地表達了你(可能)實際上並不關心顯示的特定字符串的事實

我也認爲它是一個好處,當測試因缺少消息鍵而失敗時,我想知道。

3

您正在使用EasyMock創建實例。相反,使用靜態方法時,您必須模擬(使用PowerMock)。

它應該工作一樣,(與EasyMock的3.0和1.5 PowerMock測試,雖然):

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ResourceBundle.class) 
public class TestSuite { 
    @Before 
    public void setUp() throws Exception { 
     // mock the class for one method only 
     PowerMock.mockStaticNice(ResourceBundle.class, "getString"); 

     // define mock-behaviour on the class, when calling the static method 
     expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue"); 

     // start the engine 
     PowerMock.replayAll(); 
    } 
} 

(我知道這個問題是一個幾個月大,但它可能會幫助別人,雖然)

+0

我也面臨同樣的問題。但這仍然沒有幫助。你只是指最終方法還是靜態方法? – Siddharth

+0

@Siddharth {{PowerMock.mockStaticNice()}}嘲笑一個類的靜態方法,但保持其餘方法不變。如果這個線程不能幫助你,你應該創建一個新的問題,因爲看起來你有不同的問題。 – Andy

+0

感謝您的回覆@Andy。但是這個線程的主題討論了最終方法,但是你正在談論靜態方法。我錯過了什麼嗎? 我的問題是,有「公共最終空白」的方法,我試圖模擬和測試調用實際的方法,而不是模擬。上述問題與我正在談論的問題有何不同?對不起,如果我錯過了一點。 – Siddharth

1

嘗試使用:

@PrepareForTest({ResourceBundle.class, BeanBeingTested.class}) 

隨着在PrepareForTest唯一的ResourceBundle模擬將工作時,從你的單元測試方法直接調用,而是從BeanBeingTested你叫當G和正在使用的真實方法。

Powermock文檔缺乏這方面。

相關問題