Mockito模拟UserRepository返回Optional异常:空Optional而非预期实例
Mock的UserRepository返回空Optional,业务方法抛出UserNotFoundException问题排查
问题根源
你的UserRepository中存在两个重载的findByTelegramId方法:
Optional<AppChatMember> findByTelegramId(long telegramId);(基本类型long参数)Optional<AppChatMember> findByTelegramId(Long telegramId);(包装类型Long参数)
业务方法getByTelegramId传入的是基本类型long参数,调用的是第一个重载方法;但测试中使用when(userRepository.findByTelegramId(anyLong())).thenReturn(...)时,Mockito默认匹配的是包装类型Long的重载方法,导致实际调用的方法未被Mock,返回默认的空Optional,最终触发UserNotFoundException。
解决方案
修改测试中的Mock匹配逻辑,明确指定匹配基本类型long的重载方法:
方案1:明确指定参数匹配类型(推荐)
// 使用eq匹配具体的long值,精准匹配目标重载方法 when(userRepository.findByTelegramId(eq(expectedTelegramId))).thenReturn(Optional.of(user)); // 或者用anyLong()+类型限定,匹配任意long类型参数 when(userRepository.findByTelegramId(ArgumentMatchers.anyLong())).thenReturn(Optional.of(user));
方案2:强制转换参数类型
// 通过强制转换明确匹配基本类型long的重载方法 when(userRepository.findByTelegramId((long) anyLong())).thenReturn(Optional.of(user));
验证环节优化
验证时也可明确参数类型,确保验证的是正确的方法重载:
verify(userRepository, times(1)).findByTelegramId((long) expectedTelegramId);
补充建议
若无特殊业务需求,建议删除UserRepository中冗余的重载方法,统一参数类型(比如只用基本类型long或包装类型Long),避免后续再出现方法匹配类问题。
内容的提问来源于stack exchange,提问作者KripDo
相关产品推荐
相关产品推荐

