Mockito是否支持嵌套Spy?测试时Stub不生效该如何处理?
问题原因
该问题和Mockito是否支持嵌套Spy无关,是测试代码逻辑配置错误导致:
你手动调用classA.getSomeStuff()生成了一个ClassB实例并对其做Spy、Stub操作,但调用classA.start()时,方法内部会再次调用getSomeStuff()生成一个全新的ClassB实例,和你之前Spy的实例是两个完全独立的对象,你编写的Stub规则只作用于你手动生成的Spy对象,自然不会对start方法内部生成的实例生效。
修复方案
最简洁合理的实现方式是直接对Spy的ClassA实例的getSomeStuff()方法进行Stub,让它直接返回你预先配置好Stub规则的Spy ClassB实例,示例代码如下:
@Test void test1() { // 构造ClassB的Spy实例并配置Stub规则 ClassB classB = spy(new ClassB(render, response)); doReturn(classC).when(classB).getResults(); // Stub ClassA的getSomeStuff方法,使其直接返回上面构造的Spy实例 doReturn(classB).when(classA).getSomeStuff(); classA.start(); // 此处补充测试断言逻辑 }
补充说明
- 要确保测试类上添加了
@ExtendWith(MockitoExtension.class)注解,保证Mockito的@Spy、@Mock注解才能正常生效。 - ClassA本身是被Spy的对象,其protected权限的
getSomeStuff方法支持直接Stub,完全符合Mockito的使用规范。 - 如果
getSomeStuff是private方法,也可以通过反射替换方法返回值,或者使用Mockito的mockConstruction能力Mock ClassB的构造方法实现需求,但这两种方式都会增加测试复杂度,优先推荐使用上述直接Stub父类方法的方案,更简洁易维护。
内容的提问来源于stack exchange,提问作者Tim Eichmann
相关产品推荐
相关产品推荐

