在保留超类实现的同时模拟子类方法
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中文网其他相关文章!