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

Controller单元测试执行MockMvc时出现NullPointerException问题

解决Controller单元测试中的NullPointerException问题

问题根源分析

你的测试报错是因为Controller里的userService实例为null,同时代码里还有几个关键错误:

  1. 静态方法调用错误:Controller的getUsersForList方法里写的是UserService.getUsersForList()(大写U),这是调用静态方法,但你的getUsersForList应该是实例方法,必须用成员变量userService(小写u)调用
  2. Service实例化方式错误:Controller构造函数里手动new UserService(...),没有通过Spring依赖注入,导致测试中用@MockBean创建的UserService mock对象无法替换掉Controller里自己new的实例
  3. 测试类缺少必要注解:@AutoConfigureMockMvc需要配合@SpringBootTest才能启动Spring上下文,否则MockBean和MockMvc都无法正常工作
  4. 类型拼写错误:Controller方法返回的是List<UserData>,但你写的是List<UsersData>,多了个s,会导致编译错误

修复后的Controller代码

@RestController
@CrossOrigin
@RequestMapping("/api/users")
public class UserMigrationController {

    private final UserService userService;
    @Value("${SOURCE_DNS}")
    private String sourceDns;

    // 推荐用构造注入,让Spring管理UserService实例
    @Autowired
    public UserMigrationController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping(value = "/getUsers", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<UserData>> getUsersForList() throws Exception {
        // 修正为实例方法调用,同时修正泛型类型
        List<UserData> usersDataList = userService.getUsersForList();
        return new ResponseEntity<>(usersDataList, HttpStatus.OK);
    }
}

修复后的测试类代码

@SpringBootTest
@AutoConfigureMockMvc
class UserMigrationControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    // 去掉不必要的MockitoAnnotations.openMocks(this),@MockBean由Spring自动处理
    @Test
    void should_get_users_for_list() throws Exception {
        String id = "id";
        String name = "name";
        UserData userData = new UserData(id, name);
        List<UserData> response = new ArrayList<>();
        response.add(userData);
        
        // 这里mock的是实例方法,符合修复后的Controller调用逻辑
        when(userService.getUsersForList()).thenReturn(response);

        mockMvc.perform(MockMvcRequestBuilders.get("/api/users/getUsers")
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk());
    }
}

额外说明

  • 构造注入是Spring官方推荐的依赖注入方式,它能保证依赖不可变,同时方便单元测试
  • @MockBean会自动替换Spring上下文中对应的真实Bean,所以必须让Controller通过Spring注入UserService,而不是自己new
  • 测试类里的@SpringBootTest会启动完整的Spring上下文,配合@AutoConfigureMockMvc可以轻松测试Controller的HTTP请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:45:33