Mockito Spy使用时Mock函数未被调用的问题排查
Mockito测试中Mock对象未调用问题排查与解决
场景与代码
类A的fun()方法会调用依赖类B的fun1()、类C的fun2(),同时调用自身的fun3()。
类A代码
class A { B b; C c; @Inject A(B b, C c) { this.b = b; this.c = c; } void fun() { try { b.fun1(); c.fun2("success"); } catch (Exception e) { c.fun2("Failure"); } fun3(); } void fun3() { // 业务代码 } }
JUnit测试代码
public class ATest { @Mock B b; @Mock C c; @InjectMocks A a; @Mock Fun1Response fun1response; @Test public void myTest() { when(b.fun1(any())).thenReturn(fun1response); A aSpy = Mockito.spy(a); doNothing().when(aSpy).fun3(); doNothing().when(c).fun2(any()); aSpy.fun(); verify(c).fun2(eq("success")); verify(a).fun3(); } }
运行错误
期望但未调用: c.fun2(<any>) [junit] 实际:与该Mock对象无任何交互。
问题原因分析
Mockito注解未初始化:测试类使用了
@Mock和@InjectMocks注解,但未配置Mockito运行器/扩展,导致注解失效,b、c及a中的依赖均为null。调用b.fun1()时抛出NullPointerException,进入catch块后调用c.fun2()再次抛出NullPointerException,该异常未被外层捕获,导致fun()方法提前终止,c.fun2()从未实际执行。方法存根签名不匹配:类A中调用的是无参的
b.fun1(),但测试代码中使用了带参数匹配器的when(b.fun1(any())),触发Mockito参数匹配器使用错误,存根无效;若B.fun1()是void方法,使用thenReturn()存根的写法本身错误(void方法需用doNothing()/doThrow())。Verify对象不匹配:测试中调用的是
aSpy.fun(),但verify(a).fun3()验证的是原始a对象的方法,而非被调用的aSpy,会导致验证失败。
解决步骤
步骤1:初始化Mockito注解
根据JUnit版本添加对应配置:
- JUnit 4:在测试类上添加
@RunWith(MockitoJUnitRunner.class),或在@Before方法中调用MockitoAnnotations.initMocks(this); - JUnit 5:在测试类上添加
@ExtendWith(MockitoExtension.class)
示例(JUnit 5):
@ExtendWith(MockitoExtension.class) public class ATest { // 原有代码 }
步骤2:修正方法存根
若B.fun1()是无参void方法,修正存根代码:
// 替换原有的when(b.fun1(any())).thenReturn(fun1response); doNothing().when(b).fun1();
若B.fun1()是有参方法,需确保类A调用与测试存根参数匹配,例如类A中调用b.fun1("param"),则存根改为:
when(b.fun1(eq("param"))).thenReturn(fun1response);
步骤3:修正Verify对象
将验证fun3()的对象改为aSpy:
// 替换原有的verify(a).fun3(); verify(aSpy).fun3();
完整修正后的测试代码
@ExtendWith(MockitoExtension.class) public class ATest { @Mock B b; @Mock C c; @InjectMocks A a; @Test public void myTest() { // 修正fun1()的存根(假设是无参void方法) doNothing().when(b).fun1(); A aSpy = Mockito.spy(a); doNothing().when(aSpy).fun3(); doNothing().when(c).fun2(any()); aSpy.fun(); verify(c).fun2(eq("success")); // 修正verify的对象为aSpy verify(aSpy).fun3(); } }
内容的提问来源于stack exchange,提问作者SAIKAT CHAKRABORTY
相关产品推荐
相关产品推荐

