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

使用@SpringBootTest和@ExtendWith(MockitoExtension.class)时Mock返回null

问题原因及解决方案

原因分析

你遇到的userInfoDto为null的问题,核心原因是**@Mock注解的对象没有被注册到Spring上下文**,同时测试注解混用导致Mock实例无法被正确识别:

  • @SpringBootTest会启动完整的Spring上下文,管理所有Spring Bean;但@Mock只是Mockito创建的一个孤立Mock对象,不会被Spring上下文接管。
  • 如果你的测试中存在依赖UserInfoDto的Spring Bean,这个Bean无法获取到你用@Mock创建的实例,要么拿到Spring自动生成的默认实例(如果UserInfoDto是Spring管理的Bean),要么就是null。
  • 另外,@SpringBootTest已经内置了Mockito的支持,额外添加@ExtendWith(MockitoExtension.class)属于冗余配置,不会直接导致问题,但没必要保留。

解决方案

方案一:改用@MockBean替换@Mock(推荐用于集成测试)

@MockBean是Spring Boot提供的专属注解,它会将Mock对象注册到Spring上下文中,自动替换掉同类型的原有Bean(如果存在),确保所有依赖该类型的Spring Bean都能注入这个Mock实例。修改代码如下:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IntegrationTest {
    @Autowired
    private UserRepository userRepository;

    @MockBean
    private UserInfoDto userInfo;

    @BeforeEach
    public void init() {
        when(userInfo.getXCaller()).thenReturn("Test");
    }

    // 编写你的测试方法
}

方案二:切换为纯单元测试(无需Spring上下文)

如果你的测试不需要启动完整Spring上下文(比如仅测试某个服务的业务逻辑,不需要数据库等Spring组件),可以移除@SpringBootTest,用@InjectMocks将Mock对象注入到被测试对象中:

@ExtendWith(MockitoExtension.class)
public class UnitTest {
    @Mock
    private UserRepository userRepository;
    @Mock
    private UserInfoDto userInfo;
    @InjectMocks
    private UserService userService; // 替换为你实际要测试的类

    @BeforeEach
    public void init() {
        when(userInfo.getXCaller()).thenReturn("Test");
    }

    // 编写你的测试方法
}

内容的提问来源于stack exchange,提问作者Tohid Makari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:22:51