使用Mockito执行JUnit测试时@InjectMocks类方法返回Null的问题
我来帮你拆解清楚这个问题的核心逻辑:
问题根源:Mock对象的默认行为
你声明的User是一个Mockito Mock对象,这类对象的所有非void方法默认都会返回对应类型的空值(比如String返回null、int返回0)。
当你调用user.setMyuserString("UserInput")时,这个操作并没有真的修改Mock对象内部的userString字段——Mock的setMyuserString方法只是被Mockito记录了「被调用过」的行为,但不会执行任何实际的赋值逻辑。
而verify(user).setMyuserString("UserInput")能通过,是因为Mockito仅仅在验证这个方法确实被调用过,且传入的参数是"UserInput",它完全不关心Mock对象的内部状态变化。
当你调用manager.managerLogString()时,它会触发Mock的user.logMyUserString()方法,而这个方法默认返回null,所以你最终得到的就是null值。
解决方案:Stub Mock对象的方法返回值
要让managerLogString()返回预期的"UserInput",你需要明确指定Mock的logMyUserString()方法的返回值,也就是用when(...).thenReturn(...)来「打桩」这个方法:
修正后的测试代码
@Test public void test() { // 告诉Mockito:当调用user.logMyUserString()时,返回"UserInput" when(user.logMyUserString()).thenReturn("UserInput"); TestingString = manager.managerLogString(); // 验证logMyUserString方法确实被调用了 verify(user).logMyUserString(); System.out.println(TestingString); assertEquals("UserInput", TestingString); }
额外补充
如果你希望Mock对象的setter方法真的修改内部状态,可以考虑使用@Spy替代@Mock——Spy对象会优先调用真实的方法逻辑,同时你也可以选择性地打桩某些方法。不过在这个测试场景下,用打桩的方式更符合Mockito的设计思路:我们只需要验证依赖的交互行为和返回结果,不需要依赖真实对象的内部状态。
内容的提问来源于stack exchange,提问作者Leanne

