SpringBoot使用MockMVC测试用户注册接口返回200但未创建用户
问题根因
- 核心原因:测试类中使用
@MockBean注解注入UserService,该注解会将Spring容器内真实的业务实现替换为Mockito生成的模拟对象,模拟对象的所有方法默认是空实现,不会执行真实的用户写入逻辑,自然不会将用户数据存入数据库。 - 不规范写法:MockMvc是服务端模拟请求工具,不需要携带完整域名端口,你填写的
http://localhost:8080/users/signup可以简化为相对路径/users/signup,不过该问题不会影响本次测试结果。 - 对实体ID的误解:你担心用
User实体测试会携带ID字段,实际上只要使用User类的public User(String username, String password)构造方法创建对象,ID为long基础类型的默认值0,只需要在ID字段上添加@JsonIgnore注解,就可以在JSON序列化时自动忽略ID,完全不需要额外定义TestUser类。
解决方案
根据你的测试目标选择对应方案:
方案1:集成测试(真实执行业务逻辑写入数据库)
- 将测试类中的
@MockBean UserService userService;改为@Autowired UserService userService;,注入真实的业务实现类。 - 修正MockMvc请求路径:将
post("http://localhost:8080/users/signup")改为post("/users/signup")。 - (可选)删除冗余的
TestUser类,直接用User实体构造测试数据:
User testUser = new User("timcard", "TimCard72-");
如果需要避免ID被序列化到请求体中,可在User类的id字段上添加@JsonIgnore注解。
4. (可选)建议配置H2内存数据库作为测试数据源,避免测试数据污染正式库,同时可添加@Transactional注解在测试类上,测试完成后自动回滚所有数据。
方案2:单元测试(仅验证Controller调用逻辑,不操作数据库)
如果你不需要真实写入数据库,仅验证Controller是否正确调用了Service层方法,保留@MockBean配置,补充Mock规则和验证逻辑即可:
@Test public void addUserTest() throws Exception { TestUser testUser = new TestUser("timcard", "TimCard72-"); // 预先配置Mock方法的行为 doNothing().when(userService).signUpUser(any(User.class)); mvc.perform(post("/users/signup") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(asJsonString(testUser))) .andExpect(status().isOk()); // 验证Service层方法被正确调用 verify(userService, times(1)).signUpUser(any(User.class)); }
内容的提问来源于stack exchange,提问作者Tim Hudson
相关产品推荐
相关产品推荐

