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

如何用JUnit测试Spring Boot请求模型类的字段验证及toString方法

为Spring Boot请求模型编写JUnit测试用例(满足校验规则+高覆盖率)

前提准备

确保项目依赖包含以下内容(Maven示例):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>

假设你的请求模型类RequestModel定义如下(带校验注解):

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

public class RequestModel {
    @NotBlank(message = "id不能为空且长度必须为8")
    @Size(min = 8, max = 8, message = "id长度必须为8")
    private String id;

    @NotNull(message = "revision不能为null")
    private Integer revision;

    @NotBlank(message = "state不能为空")
    @Size(min = 2, max = 2, message = "state长度必须为2")
    @Pattern(regexp = "^[A-Z]{2}$", message = "state必须为两位大写字母")
    private String state;

    // 全参构造器
    public RequestModel(String id, Integer revision, String state) {
        this.id = id;
        this.revision = revision;
        this.state = state;
    }

    // toString方法(Lombok自动生成或手动编写)
    @Override
    public String toString() {
        return "RequestModel{" +
                "id='" + id + '\'' +
                ", revision=" + revision +
                ", state='" + state + '\'' +
                '}';
    }

    // getter、setter方法省略
}

测试类实现

创建RequestModelTest类,用JUnit 5 + AssertJ + Bean Validator完成测试:

import org.junit.jupiter.api.Test;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;

class RequestModelTest {
    private final Validator validator;

    // 初始化校验器
    public RequestModelTest() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    // 合法场景:所有字段符合规则,无校验错误
    @Test
    void shouldPassValidationWhenAllFieldsAreValid() {
        RequestModel validModel = new RequestModel("12345678", 1, "AB");
        Set<?> violations = validator.validate(validModel);
        assertThat(violations).isEmpty();
    }

    // --- Id字段校验测试 ---
    @Test
    void shouldFailValidationWhenIdIsNull() {
        RequestModel model = new RequestModel(null, 1, "AB");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(2);
        assertThat(violations).extracting("message")
                .contains("id不能为空且长度必须为8", "id长度必须为8");
    }

    @Test
    void shouldFailValidationWhenIdIsEmpty() {
        RequestModel model = new RequestModel("", 1, "AB");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(2);
        assertThat(violations).extracting("message")
                .contains("id不能为空且长度必须为8", "id长度必须为8");
    }

    @Test
    void shouldFailValidationWhenIdLengthIsLessThan8() {
        RequestModel model = new RequestModel("1234567", 1, "AB");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(1);
        assertThat(violations).extracting("message")
                .contains("id长度必须为8");
    }

    @Test
    void shouldFailValidationWhenIdLengthIsMoreThan8() {
        RequestModel model = new RequestModel("123456789", 1, "AB");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(1);
        assertThat(violations).extracting("message")
                .contains("id长度必须为8");
    }

    // --- Revision字段校验测试 ---
    @Test
    void shouldFailValidationWhenRevisionIsNull() {
        RequestModel model = new RequestModel("12345678", null, "AB");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(1);
        assertThat(violations).extracting("message")
                .contains("revision不能为null");
    }

    // --- State字段校验测试 ---
    @Test
    void shouldFailValidationWhenStateIsNull() {
        RequestModel model = new RequestModel("12345678", 1, null);
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(3);
        assertThat(violations).extracting("message")
                .contains("state不能为空", "state长度必须为2", "state必须为两位大写字母");
    }

    @Test
    void shouldFailValidationWhenStateIsEmpty() {
        RequestModel model = new RequestModel("12345678", 1, "");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(3);
        assertThat(violations).extracting("message")
                .contains("state不能为空", "state长度必须为2", "state必须为两位大写字母");
    }

    @Test
    void shouldFailValidationWhenStateLengthIsNot2() {
        RequestModel model = new RequestModel("12345678", 1, "A");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(2);
        assertThat(violations).extracting("message")
                .contains("state长度必须为2", "state必须为两位大写字母");
    }

    @Test
    void shouldFailValidationWhenStateDoesNotMatchRegex() {
        RequestModel model = new RequestModel("12345678", 1, "ab");
        Set<?> violations = validator.validate(model);
        assertThat(violations).hasSize(1);
        assertThat(violations).extracting("message")
                .contains("state必须为两位大写字母");
    }

    // --- toString方法测试 ---
    @Test
    void shouldReturnCorrectToStringValue() {
        RequestModel model = new RequestModel("12345678", 1, "AB");
        String toStringResult = model.toString();
        assertThat(toStringResult)
                .contains("id='12345678'")
                .contains("revision=1")
                .contains("state='AB'")
                .startsWith("RequestModel{")
                .endsWith("}");
    }
}

覆盖率说明

以上测试覆盖了:

  • 所有字段的合法/非法校验场景,覆盖了校验注解的全部分支逻辑
  • toString方法的输出验证
  • 模型类的构造器逻辑

运行测试后,代码覆盖率会轻松超过90%;如果模型类包含Lombok生成的getter/setter,可在测试中调用这些方法(比如assertThat(model.getId()).isEqualTo("12345678"))进一步提升覆盖率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:35:18