在保留超類實現的同時模擬子類方法
Mockito 是一種廣泛使用的Java 模擬框架,經常面臨選擇性模擬特定方法的挑戰在類別層次結構內。本文解決了您只想模擬從超類別繼承的方法的呼叫的場景。
問題陳述
考慮以下類別結構:
<code class="java">class BaseService { public void save() {...} } public Childservice extends BaseService { public void save(){ //some code super.save(); } } </code>
在單元測試中,您可能只想模擬對super.save()的第二次調用,而不影響ChildService 中的實作。
解決方案
雖然通常不建議出於測試目的重構現有的類別層次結構,但有一些方法可以在不修改程式碼庫的情況下解決此挑戰。
考慮以下方法:
<code class="java">class BaseService { public void validate(){ fail(" I must not be called"); } public void save(){ //Save method of super will still be called. validate(); } } class ChildService extends BaseService{ public void load(){} public void save(){ super.save(); load(); } } @Test public void testSave() { ChildService classToTest = Mockito.spy(new ChildService()); // Prevent/stub logic in super.save() Mockito.doNothing().when((BaseService)classToTest).validate(); // When classToTest.save(); // Then verify(classToTest).load(); }</code>
此解決方案利用Mockito 的 Mockito.spy() API 用於包裝 ChildService 類別的實例。然後,它使用 Mockito.doNothing() 重寫 BaseService(超類別)的 validate() 方法。這確保了測試期間避免使用 validate() 中的邏輯。結果,ChildService.save() 的真正實作被調用,而對 super.save() 的調用被有效地存根。
附加說明
This應謹慎使用技術,因為存根或模擬外部方法可能會導致脆弱的測試並影響測試結果的準確性。然而,當重構類別層次結構不可行時,它可能是實用的解決方案。
以上是如何在 Mockito 中保留超類別實作的同時模擬子類別方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!