Mockito When...thenReturn失效:LoginController单元测试异常排查
问题排查与解决
1. 确认@Mock注解的初始化配置
如果使用@Mock注解,必须确保测试类启用Mockito的扩展支持:
- JUnit 5:测试类添加
@ExtendWith(MockitoExtension.class) - JUnit 4:测试类添加
@RunWith(MockitoJUnitRunner.class)
缺少这个配置时,@Mock标注的对象不会被Mockito正确代理,本质还是空对象或原始类实例,导致桩方法完全不生效。你手动调用mock(LoginDao.class)能消除异常,就是因为手动完成了Mockito的代理初始化,但还需要确保这个mock对象被注入到LoginController中。
2. 检查Mock对象是否注入到LoginController
确保你的LoginController实例是通过@InjectMocks注解创建的,而非手动new:
@ExtendWith(MockitoExtension.class) class LoginControllerTest { @Mock private LoginDao loginDao; @InjectMocks private LoginController loginController; // Mockito会自动把loginDao注入这里 // 测试方法... }
如果手动new LoginController(),Controller内部的LoginDao还是原始对象,根本不会使用你设置了桩的mock实例,自然返回null。
3. 检查桩方法的参数匹配器
确认anyString()是导入的org.mockito.ArgumentMatchers.anyString(),而非其他包的同名方法。匹配器导入错误会导致参数匹配失败,Mockito无法触发你设置的thenReturn(admin),返回默认的null值。
另外,若测试中实际调用getAdminDetails时传入了null参数,anyString()不会匹配null(它只匹配非null的字符串),这种情况需要改用nullable(String.class)或者直接指定具体参数值来匹配。
4. 关于UnneccessaryStubbingException
这个异常的本质是:你设置了桩方法,但测试过程中没有调用到这个桩方法(或调用的参数和桩的匹配器不匹配)。之前用@Mock时出现这个异常,大概率是因为mock对象没被注入到Controller,导致实际调用的不是你设置桩的那个mock,Mockito认为你定义了无用的桩。手动mock后如果还是返回null,说明mock对象仍未被正确关联到Controller,或者参数匹配失败。
内容的提问来源于stack exchange,提问作者Rishi Mudaliar
相关产品推荐
相关产品推荐

