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

Spring测试中JpaRepository.save返回Null的问题与解决

为什么Mockito测试中userRepository.save()返回null导致空指针?怎么解决?

问题原因

你通过Mockito创建了UserRepository的mock对象,但没有为这个mock对象的save()方法指定返回值。Mockito对mock对象的方法调用有默认行为:

  • 引用类型的返回值默认是null
  • 基本类型返回对应默认值(比如int返回0)

所以在你最初的测试代码里,userService.addUser(user)调用userRepository.save(user)时,mock的仓库直接返回了null,导致result变量为null,后续调用result.getUsername()自然抛出空指针异常。

解决方案

核心是给mock的userRepository.save()方法明确指定返回值,常用两种写法:

方式1:BDD风格(given())

像你补充的代码那样,在测试的准备阶段指定返回值:

given(userRepository.save(user)).willReturn(user);

这样当userRepository.save(user)被调用时,就会返回你预先构造好的user对象,而非默认的null。

方式2:传统Mockito风格(when())

也可以用更通用的传统写法,还支持模糊匹配参数:

// 匹配任意User类型的参数,返回指定user对象
when(userRepository.save(any(User.class))).thenReturn(user);

如果不需要严格匹配传入的user实例,用any(User.class)能提升测试的灵活性。

针对参数化测试的修改方案

如果你想保留最初的参数化测试,只需补充mock方法的返回值配置即可,同时别忘了给PasswordEncoder的encode()方法也指定返回值(否则密码会被设为null):

@ParameterizedTest
@CsvSource({
        "username, password, 1, test@test.com, admin, true",
})
void checkIfUserCanBeAdded(String username,String password,int group_id,String email,String role,Boolean active){
    //given
    User user = new User(username, password, group_id, email, role, active);
    given(userRepository.save(user)).willReturn(user);
    given(passwordEncoder.encode(password)).willReturn("encoded-password");

    //when
    User result = userService.addUser(user);

    //then
    assertSame(result.getUsername(), user.getUsername());
    assertEquals("encoded-password", result.getPassword());
    assertSame(result.getGroup_id(), user.getGroup_id());
    assertSame(result.getEmail(), user.getEmail());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:05:20