2012-11-14 69 views
2

我有一個類,它擴展了我不擁有的另一個類。我的課程用於計算針對父類的很多調用中的幾個指標。有沒有一種方法可以在單元測試中嘲笑父類(同時保留我孩子的邏輯),以確保針對我的孩子的調用總是「通過」到包裝父代?模擬一個父類來測試一個包裝類

在代碼

Class SlowClass { 
    public Object doFoo(Object obj) { 
     //... 
    } 
    public Object doBar(Object obj) { 
     //... 
    } 

    // Many more methods I don't care about. 

} 

Class SlowClassWrapper extends SlowClass { 
    public Object doFoo(Object obj) { 
     //... 
     Object toReturn = super.doFoo(obj) 
     //... 
     return toReturn; 
    } 
    public Object doBar(Object obj) { 
     //... 
     Object toReturn = super.doFoo(obj) 
     //... 
     return toReturn; 
    } 
} 

我想以某種方式模擬出SlowClass.doFoo,使SlowClassWrapper.doFoo使得沒有實際進行調用其父的電話。然後我想確認obj完好無損,並且SlowClass.doFoo的響應恢復原狀。

回答

3

一般來說,這不是模擬框架可以在Java中愉快做到的事情。您可能想考慮重構您的代碼以使用組合而不是繼承。然後,您可以將SlowClass實例注入到包裝的構造函數中,通過定期模擬來實現簡單的可測試性。

對於什麼是值得的,Mockito和PowerMock都不能嘲笑超級方法:請參見this answerthis discussion

+0

感謝。構圖是可能的,但緩慢的庫正在開發中(我們每隔幾個月就會推出新版本),而這個類有約60種方法。煩人。 –

1

我會做這樣的事情:

public class SlowClassWrapper { 
    /** wrapped parent */ 
    public final SlowClass parent; 

    public SlowClassWrapper() { 
     this(new SlowClass()); 

    @VisibleForTesting 
    protected SlowClassWrapper(SlowClass parent) { 
     this.parent = parent; 
    } 

    public Object doFoo(Object obj) { 
     //... 
     Object toReturn = parent.doFoo(obj) 
     //... 
     return toReturn; 
    } 

    public Object doBar(Object obj) { 
     //... 
     Object toReturn = parent.doFoo(obj) 
     //... 
     return toReturn; 
    } 
} 

使用Mockito和JUnit

@RunWith(MockitoJUnitRunner.class) 
public class SlowClassWrapperTest { 
    /** parent mock */ 
    @Mock 
    private SlowClass parentMock; 

    /** instance under tests */ 
    private SlowClassWrapper instance; 

    @Before 
    public void setUp() { 
     this.instance = new SlowClassWrapper(this.parentMock); 
    } 

    @Test 
    public void testDoFoo() { 
     final Object obj1 = new Object(); 
     final Object obj2 = new Object(); 
     Mockito.doReturn(obj2).when(this.parentMock).doFoo(Matchers.any()); 
     assertEquals(obj2, this.instance.doFoo(obj1)); 
     Mockito.verify(this.parentMock).doFoo(obj1); 
     Mockito.verifyNoMoreInteractions(this.parentMock); 
    } 

    @Test 
    public void testDoBar() { 
     final Object obj1 = new Object(); 
     final Object obj2 = new Object(); 
     Mockito.doReturn(obj2).when(this.parentMock).doBar(Matchers.any()); 
     assertEquals(obj2, this.instance.doBar(obj1); 
     Mockito.verify(this.parentMock).doBar(obj1); 
     Mockito.verifyNoMoreInteractions(this.parentMock); 
    } 
} 

(未測試)

+0

這是可能的組成,如你演示。我希望有一個更好的方法,但這似乎並不存在。 –

相關問題