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

Spring Boot单元测试Mock Repository无效,Service调用真实Repo报错求助

解决Spring Boot Service单元测试中Mock Repository未生效的问题

嘿,我帮你排查下问题,你现在的Mock没生效主要是配置冲突加上拼写错误在拖后腿,咱们一步步来解决:

1. 先修正致命的拼写错误

你的代码里有两处拼写错误,这会导致Mockito根本找不到要Mock的Repository:

  • 类名:UserRepostiory → UserRepository(少了个t)
  • 变量名:userRepostitory → userRepository(同样少了个t)

2. 选择正确的测试模式(二选一)

你现在的测试混合了「Spring集成测试」和「纯Mockito单元测试」的配置,这是Mock失效的核心原因。根据你的需求(单元测试Service),推荐下面两种方案:

方案一:纯Mockito单元测试(推荐,轻量快速)

单元测试不需要加载整个Spring上下文,只用Mockito的扩展就能完成。去掉所有Spring相关的注解,只保留@ExtendWith(MockitoExtension.class):

@ExtendWith(MockitoExtension.class)
public class UserTest{
    @InjectMocks
    private UserServiceImpl userService;
    @Mock
    private UserRepository userRepository; // 已修正拼写

    // 注意:Junit5用@BeforeEach替代Junit4的@Before
    @BeforeEach
    public void setUp() {
        User user = new User(1L, "email@email", "name");
        when(userRepository.findById(1L)).thenReturn(Optional.of(user)); // 已修正拼写
    }

    @Test
    public void findUserByIdReturnsUser() {
        User user = userService.getById(1L); 
        assertEquals(1L, user.getId());
    }
}

为什么原来的配置不行?

  • @SpringBootTest会强制加载整个Spring应用上下文,这时候Spring会自行创建UserServiceImpl的实例,而不是用Mockito的@InjectMocks来注入Mock的Repository,所以实际调用的是真实的Repository(测试环境的数据库大概率是空的,所以找不到用户)。
  • 同时使用@ExtendWith(SpringExtension.class)和@ExtendWith(MockitoExtension.class)会造成依赖注入的冲突,Spring的扩展会优先接管,导致Mockito的Mock无法被注入到Service实例中。

方案二:Spring集成测试(如果需要Spring上下文)

如果你因为某些原因必须加载Spring上下文(比如需要用到Spring的其他Bean或配置),那应该用@MockBean替代@Mock和@InjectMocks,这样Spring会把Mock的Repository注册到上下文里,替换掉真实的Bean:

@SpringBootTest
@ActiveProfiles("test")
public class UserTest{
    @Autowired
    private UserServiceImpl userService;
    @MockBean
    private UserRepository userRepository; // 已修正拼写

    @BeforeEach
    public void setUp() {
        User user = new User(1L, "email@email", "name");
        when(userRepository.findById(1L)).thenReturn(Optional.of(user));
    }

    @Test
    public void findUserByIdReturnsUser() {
        User user = userService.getById(1L); 
        assertEquals(1L, user.getId());
    }
}

最后总结

  • 做Service单元测试优先选纯Mockito方案,不需要加载Spring上下文,测试速度更快,也更符合单元测试的隔离原则。
  • 拼写错误很容易被忽略,一定要检查变量名和类名的拼写是否一致,Mockito对名称匹配很严格。
  • 如果是集成测试(需要Spring上下文),就用@SpringBootTest配合@MockBean来替换真实的Repository。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:12:46