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

如何使用JUnit5测试@Validated类中带@NotBlank注解的方法参数校验逻辑

如何使用JUnit5测试@Validated类中带@NotBlank注解的方法参数校验逻辑

我之前刚好处理过类似的场景——当校验规则直接标注在方法参数上而不是实体类里时,常规的实体校验测试思路确实不太适用。不过结合JUnit 5和Spring的测试支持,我们可以轻松验证这个方法级的校验逻辑,下面一步步来拆解:

核心思路说明

因为@Validated是Spring提供的注解,它依靠AOP切面来实现方法级的参数校验,必须让Spring容器管理目标类的实例,才能触发校验逻辑。如果直接new Foo()调用方法,Spring的校验切面根本不会介入,自然不会触发校验。所以我们的测试需要启动Spring上下文,让Spring来创建并管理Foo的实例。

测试步骤与代码示例

1. 确保依赖到位

如果是Spring Boot项目,只需要引入spring-boot-starter-test依赖即可,它已经包含了JUnit 5、Spring Test以及Jakarta Validation的相关依赖:

<!-- Maven依赖示例 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

2. 编写测试类

我们可以用@ExtendWith(SpringExtension.class)来启用Spring的JUnit 5支持,再通过@ContextConfiguration指定要加载的类(这里就是我们的Foo类),这样就能启动一个轻量的Spring上下文:

import jakarta.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {Foo.class})
class FooValidationTest {

    // 让Spring注入管理的Foo实例,而不是自己new
    @Autowired
    private Foo foo;

    @Test
    void bar_WithBlankBaz_ShouldThrowValidationException() {
        // 测试空字符串、null、空白字符三种场景,都会触发@NotBlank校验
        assertThrows(ConstraintViolationException.class, () -> foo.bar(""));
        assertThrows(ConstraintViolationException.class, () -> foo.bar(null));
        assertThrows(ConstraintViolationException.class, () -> foo.bar("   "));
    }

    @Test
    void bar_WithValidBaz_ShouldNotThrowException() {
        // 合法参数不会触发异常,执行方法无报错即通过测试
        foo.bar("Hello, Validation!");
    }

    // 可选:验证具体的错误提示信息
    @Test
    void bar_WithBlankBaz_ShouldReturnCorrectErrorMessage() {
        ConstraintViolationException exception = assertThrows(ConstraintViolationException.class, () -> foo.bar(""));
        // 获取第一个校验违规的信息(这里只有一个参数违规)
        String errorMsg = exception.getConstraintViolations().iterator().next().getMessage();
        // 默认@NotBlank的提示是"must not be blank",如果自定义了message就写对应的内容
        assertEquals("must not be blank", errorMsg);
    }
}

3. Spring Boot项目的简化写法

如果你的项目是Spring Boot,直接用@SpringBootTest注解就可以,它会自动扫描当前包下的组件,不需要手动指定@ContextConfiguration,测试类会更简洁:

import jakarta.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SpringBootTest
class FooValidationTest {

    @Autowired
    private Foo foo;

    @Test
    void bar_WithInvalidBaz_ThrowsException() {
        assertThrows(ConstraintViolationException.class, () -> foo.bar(""));
    }
}

关键注意点

  • 绝对不能直接new Foo()来测试,因为这样的实例不在Spring容器中,不会触发@Validated的AOP校验切面。
  • @NotBlank注解的校验规则是:字符串不能为null,且去除首尾空格后长度大于0,所以测试要覆盖这几种违规场景。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 13:08:06