2013-03-26 31 views
5

在一個方法中,我有一個異常被捕獲,我想模擬。我知道如何使用mock.doSomething()來模擬一個拋出異常的對象,但是當一個類創建一個新的實例時,我需要拋出一個遠程異常。如何在使用Mockito創建新類的實例時模擬異常

transient Bicycle bike = null; 

public Bicycle getBicycle() { 
    if (bike == null) { 
     try { 
      bike = new Bicycle(this); 
     } catch (RemoteException ex) { 
      System.out.println("No bikes found"); 
     } 
    } 
    return bike; 
} 

我希望能夠嘲笑在try塊中的一切,但我不明白你怎麼嘲笑了一類新的創作,下面一行是具體:

bike = new Bicycle(this); 

我已經嘗試了許多不同的測試的Mockito,如:

Bicycle b = mock(Bicycle.class); 
Mockito.doThrow(new RemoteException()).when(b = new Bicycle()); 

雖然我明白這個意願,不工作,我想要做類似的事情。

我已閱讀文檔的Mockito並沒有發現任何有用的:

http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

+0

可能重複[如何強制的Mockito到拋出RemoteException在JUnit測試] (http://stackoverflow.com/questions/15582395/how-to-force-mockito-to-throw-remoteexception-in-junit-test) – 2013-03-26 23:34:20

+0

@ChristofferHammarström這絕對不是重複的。我寫了上一個問題,我正在尋找兩個不同的答案。 – 2013-03-28 11:22:17

回答

3

在這種情況下,您可以使用Mockito擴展PowerMock。它允許建設者被嘲笑(見https://code.google.com/p/powermock/wiki/MockConstructor)。

在這種情況下,你會寫類似下面的測試:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ClassUnderTest.class, Bicycle.class}) 
public class ConstructorMockingTest 
{ 
    @Test 
    public void getBicycle() 
    { 
     ClassUnderTest tested = new ClassUnderTest(); 
     whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException()); 

     Bicycle bicycle = tested.getBicycle(); 

     assertNull(bicycle); 
    } 
} 

更多的例子,可以發現:https://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew/WhenNewTest.java

7

你不一般的模擬構造函數。你可以做像PowerMock這樣的工具,但我通常建議你不要。

目前,如果您想控制構建新的Bicycle時發生的情況,那麼您的代碼實際上不是可測試的。實際上是在構建一個Bicycle複雜的操作?也許你想要一個BicycleFactory,它可以作爲依賴項傳入你的課程,例如 - 然後你可以模擬BicycleFactory.createBicycle或任何你稱之爲的東西。

構造函數就像靜態方法 - 當你使用它們時,你緊緊地綁定到你調用的特定代碼;沒有像PowerMock那樣的方法來注入其他行爲的乾淨方法。

+0

我不認爲我已經說清楚了,但Bicycle是另一個類的一個實例,而不是目前這種方法的一個實例。該方法檢索實例,但如果它爲空,我想創建一個新實例。我不確定這是否會改變什麼? – 2013-03-26 21:35:43

+0

@JohnVasiliou:不,完全沒有。你仍然在調用一個構造函數 - 這根本不是你可以簡單地在測試中模擬出來的東西。 – 2013-03-27 06:45:09

+0

有很多現實世界的情況下直接實例化依賴關係是正確的。舉一個這樣的例子,考慮一個需要通過電子郵件發送通知的商業服務類;在Java中,一個衆所周知的用於電子郵件的API是[Apache Commons Email](http://commons.apache.org/proper/commons-email),您通常在其中實例化一個'Email'子類(通常是'SimpleEmail')調用幾個setter/adders,最後調用send()方法。它很簡單,面向對象,*和*易於進行單元測試。 – 2014-08-21 16:29:03

0

您的getBicycle()現在至少做了兩件事。它檢索(「獲取」)Bicycle,並創建Bicycle。理想情況下,一個方法或類應該只做一件事,並做好。

把對象的創建放在單獨的方法createBicycle()或單獨的BicycleFactory並模擬它。

相關問題