2011-08-17 39 views
6

我得到了一個使用工廠創建某個對象的類。 在我的單元測試中,我想訪問工廠的返回值。 由於工廠直接傳遞給類,並且沒有爲創建的對象提供getter,所以我需要攔截從工廠返回的對象。Mockito + Spy:如何收集返回值

RealFactory factory  = new RealFactory(); 
RealFactory spy   = spy(factory); 
TestedClass testedClass = new TestedClass(factory); 

// At this point I would like to get a reference to the object created 
// and returned by the factory. 

是否有可能訪問工廠的返回值?可能使用間諜?
我能看到的唯一方法是嘲笑工廠創建方法......

問候

+0

爲什麼'TestedClass'採取的這個工廠的依賴。它不應該只是要求工廠創建的實際班級。 ?(Demeter法) –

+0

'TestedClass'是一個OSGi組件。組件的一個方法需要每個調用一個由工廠創建的新對象。我將對象創建重構爲工廠類以提供更好的可測試性。由於創建的對象根據方法參數進行了初始化,因此無法簡單地傳入創建的對象而不是工廠。 –

回答

1

標準嘲弄的做法是:

  1. 預創建的對象你想要的工廠返回測試用例
  2. 創建工廠模擬(或間諜)
  3. 指定模擬工廠返回您的預先創建的對象。

如果你真的想擁有RealFactory動態創建的對象,你也可以繼承,並覆蓋出廠方法來調用super.create(...),那麼參考保存到測試類訪問,然後返回現場創建的對象。

24

首先,您應該將spy作爲構造函數參數傳入。

除此之外,你可以這樣做。

public class ResultCaptor<T> implements Answer { 
    private T result = null; 
    public T getResult() { 
     return result; 
    } 

    @Override 
    public T answer(InvocationOnMock invocationOnMock) throws Throwable { 
     result = (T) invocationOnMock.callRealMethod(); 
     return result; 
    } 
} 

預期用法:

RealFactory factory  = new RealFactory(); 
RealFactory spy   = spy(factory); 
TestedClass testedClass = new TestedClass(spy); 

// At this point I would like to get a reference to the object created 
// and returned by the factory. 


// let's capture the return values from spy.create() 
ResultCaptor<RealThing> resultCaptor = new ResultCaptor<>(); 
doAnswer(resultCaptor).when(spy).create(); 

// do something that will trigger a call to the factory 
testedClass.doSomething(); 

// validate the return object 
assertThat(resultCaptor.getResult()) 
     .isNotNull() 
     .isInstanceOf(RealThing.class); 
+0

感謝您的分享。恕我直言:這應該是被接受的答案。 – BetaRide