2012-04-16 145 views
6

我想使用到的Mockito單元測試一個抽象類,如本great answer.用模擬的構造函數參數嘲笑抽象類?

的訣竅是詳細的,抽象類有對被在其構造注入了戰略依賴。我創建了一個模擬策略,我希望我的模擬BaseClass實例使用模擬策略進行單元測試。

任何關於如何連線的建議?我目前沒有使用任何IoC框架,但我正在考慮Spring。也許它會做的伎倆?

// abstract class to be tested w/ mock instance 
abstract BaseClass 
{ 
    // Strategy gets mocked too 
    protected BaseClass(Strategy strategy) 
    { 
     ... 
    } 
} 

更新
按照郵件的Mockito名單,目前還沒有將參數傳遞給一個模擬的構造方式。

回答

4

我見過這種事情在春天的環境下使用Mockito完成。

如:

<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="Strategy" /> 
</bean> 

我希望幫助。

-1

你不需要做任何特別的事情。只是嘲笑豆正常人一樣:

Bean bean = mock(Bean.class); 
when(bean.process()).thenReturn(somethingThatShouldBeNamedVO); 

只是工作:)

+0

謝謝,喬丹!不幸的是,我不認爲它適用於我的情況,因爲我需要注入基礎的策略類中的特定模擬行爲。如果使用了策略的默認模擬(僅返回null,0等),則模擬的BaseClass的邏輯將會中斷。不過謝謝! – HolySamosa 2012-04-17 15:11:09

+0

這不回答這個問題。 – 2016-03-14 15:57:12

4

最終我只是使用反射來設置私有字段在我的基類,像這樣:

// mock the strategy dependency 
Strategy strategyMock = mock(Strategy.class); 
when(....).thenReturn(...); 

// mock the abstract base class 
BaseClass baseMock = mock(BaseClass.class, CALLS_REAL_METHODS); 

// get the private streategy field 
Field strategyField = baseMock.getClass().getSuperclass().getDeclaredField("_privateStrategy"); 

// make remove final modifier and make field accessible 
Field modifiersField = Field.class.getDeclaredField("modifiers"); 
modifiersField.setAccessible(true); 
modifiersField.setInt(strategyField, strategyField.getModifiers() & ~Modifier.FINAL);   
strategyField.setAccessible(true); 

// set the strategy 
strategyField.set(baseMock, strategyMock); 

// do unit tests with baseMock 
... 

會如果私人領域的名稱改變了,但它的評論,我可以忍受。這很簡單,它是一行代碼,我發現這更適合暴露任何setter或必須顯式繼承我的測試。

編輯:所以它不再是一行代碼,因爲我的私人領域需要'最終',需要一些額外的反射代碼來解決。

+1

好帖子!如果你有Spring的依賴關係,你可以用一行完成所有這些;-)。發現這個類,同時窺探春天的好東西。 'org.springframework.test.util.ReflectionTestUtils.setField(baseMock,「_privateStrategy」,strategyMock)' – 2013-09-02 23:44:50