You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mockito执行JUnit测试时@InjectMocks类方法返回Null的问题

为什么@InjectMocks的ArticleManager返回null,但Mockito的verify能通过?

我来帮你拆解清楚这个问题的核心逻辑:

问题根源: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:20:12