2014-07-25 48 views
1

我在某些單元測試中使用了PowerMockito,並且遇到了問題。我試圖測試一個創建一系列線程並運行它們的方法。在每個線程內部,我需要創建一個對象,並返回自己的模擬對象(它使http請求等)。在使用PowerMockito.whenNew(...)之前,我已經完成了這個工作,並且它工作正常,但是這似乎不起作用 - PowerMockito在線程中不工作嗎?我一直無法找到像這樣的任何其他問題或有關情況的文件。Powermockito預期的對象創建不能在預期線程中工作

一些示例代碼來幫助你想象:

for(Object object : objectList) { 
    Thread t = new Thread(new Runnable() { 
     public void run() { 
      SomeObject objectImTryingToStub = new SomeObject(); 
     } 
    }); 
} 

我使用嘗試創建對象的代碼和捕捉:

SomeObject mockSomeObject = mock(SomeObject.class); 
PowerMockito.whenNew(SomeObject.class).withNoArguments().thenReturn(mockSomeObject); 

此相同的代碼已經爲其他的測試中表現優良在同一個班級裏,他們以相同的方式成功地抓住了同一類型的對象。

任何幫助表示讚賞!謝謝

回答

1

最近我遇到了同樣的問題,並找到了解決方案。 真正發生的事情是Runnable的內部聲明正在踢你所有的嘲笑!因爲Runnable類是由Bootstrap Classloader加載的,所以PowerMock無法嘲笑其中的任何操作。 解決方案(對我來說)是聲明Runnable內部類之外的實例。

+0

太棒了,非常感謝! – radar

0

由於你沒有顯示太多的代碼,我不得不猜測你錯過了正在進行「新」調用的類的「@PrepareForTest」條目,可能是你的CUT(class在測試中)。

+0

。正如我在文章中所說的,我已經在同一個測試類中成功使用了'PowerMockito.whenNew',測試了相同的CUT,創建了同一個對象。 – radar

1

對於遇到類似問題的任何人,我已經對它進行了更深入的研究,似乎此功能不能完全與線程一起工作。我試圖讓它在創建時拋出一個FNF異常 - 在線程內部它什麼都不做,而如果我在線程段之前放置對象創建,它將按預期工作。我不確定爲什麼會出現這種情況,但至少我現在有一個明確的答案。如果有人知道此方法,請告訴我。

3

這次派對的晚了,但我認爲適當的解決方案仍然缺失。如你所知,你必須PrepareForTest這個類來做你試圖模擬的對象創建。實際上在這裏創作的班級並不是那麼明顯。該班級是內部匿名Runnable班。該類的名稱在編譯時生成,在單元測試中不容易確定。假設片段是從拉類是com.example.SomeClass你需要的聲明可能是這樣的:

@PrepareForTest(com.example.SomeClass$4.class) 

但更簡單的方法來做到這一點是使用允許通配符註釋的另一種形式:

@PrepareForTest("com.example.*") 

只是儘量保持通配符匹配器儘可能緊,所以PowerMock不必準備好每個班級在陽光下運行測試。

2

我對我的項目遇到了同樣的問題,並且在做了一些挖掘之後,實際上並不是線程導致問題本身,而是該對象是從Runnable派生的匿名類中創建的。

在PowerMock的doc中,看看第二個要點,您需要放置正在進行創建的類,而不是PrepareForTest中正在實例化的類。

因此,您需要使用PrepareForTest註釋您的測試,以準備在運行時創建的任何匿名類。通常,它將是Runnable $ n,其中n是在運行時爲您計算的某個數字。那麼你如何獲得靜態不知道的課程呢?幸運的是,PrepareForTest也接受了fullyQualifiedNames字符串,所以你需要你的PrepareForTest改變這樣的事情:

@PrepareForTest( fullyQualifiedNames = {"com.whatever_package_that_SomeObject_is_in.*"}, value = {SomeStaticlyKnowClass.class} )

我,包括已經