使用@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
相关产品推荐
相关产品推荐

