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

Spring Boot createUser接口测试失败及数据库DDL报错求助

Spring Boot createUser接口单元测试失败排查

问题背景

我在Spring Boot项目中对createUser接口的单元测试始终无法通过。最初启动服务器(执行./gradlew bootRun)和运行测试时,Hibernate执行DDL语句alter table if exists credit_card add column user integer not null时会抛出CommandAcceptanceException错误。按照建议把字段名从user改为userId后,DDL报错消失,但测试仍然不通过,希望分析问题原因。

相关代码

createUser接口实现

/**
 * 创建用户实体并保存到数据库,返回包含已保存用户ID的200响应
 * @param payload 用户信息
 * @return 包含用户ID的200 OK响应
 */
@PutMapping("/user") // 处理PUT请求
public ResponseEntity<Integer> createUser(@RequestBody CreateUserPayload payload) {
    // 根据请求体创建用户实体
    User newUser = new User(payload.getName(), payload.getEmail());

    // 保存用户到数据库
    User savedUser = this.userRepository.save(newUser);

    // 返回带用户ID的OK响应
    return ResponseEntity.ok(savedUser.getId());
}

CreateUserPayload类

@Data
public class CreateUserPayload {
    private String name;
    private String email;
}

User实体类

@Entity
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@Table(name = "MyUser")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;
    private String email;

    // TODO: 用户的信用卡
    // 提示:一个用户可以有0或多张信用卡,需要支持通过用户查信用卡、通过信用卡查用户
    private Set<Integer> creditCards = new HashSet<Integer>();

    /**
     * 为用户添加信用卡
     * @param cardId 信用卡ID
     */
    public void addCreditCard(int cardId) {
        creditCards.add(cardId);
    }

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    /*
    public int getId() {
        return this.id;
    }
     */
}

单元测试代码

预期userRepository的save方法会接收name为"John"、email为"john@example.org"的User对象:

@Test
public void shouldCreateUser() throws Exception {
    mockMvc.perform(put("/user")
                    .content("{\"name\": \"John\", \"email\": \"john@example.org\"}")
                    .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk());

    verify(ur).save(argThat(user -> user.getName().equals("John") &&
            user.getEmail().equals("john@example.org")));
}

可能的失败原因分析

  • Mock对象未正确初始化:确认测试类中userRepository(代码中的ur)是通过@Mock注解声明的,且测试类添加了@RunWith(MockitoJUnitRunner.class)或@ExtendWith(MockitoExtension.class)来启用Mockito功能。若Mock对象初始化错误,verify方法会因找不到有效实例而失败。
  • JSON序列化问题:检查请求JSON格式是否正确,比如字段名拼写、大小写是否与CreateUserPayload匹配。可在createUser方法中加断点,确认接收到的payload属性是否正确赋值。
  • MockMvc配置错误:确保mockMvc是通过@Autowired注入,或者用MockMvcBuilders.standaloneSetup(controller).build()正确构建,否则请求无法映射到目标接口。
  • 测试环境干扰:若测试类使用了@SpringBootTest且未排除数据库自动配置,可能会启动真实数据源,导致Mock的userRepository未生效。建议在测试类中使用@WebMvcTest仅加载控制器层,避免不必要的组件初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:08:10