java - @Valid不会触发@Repository中的验证

标签 java spring-boot unit-testing bean-validation jedis

我正在编写单元测试来检查输入验证在我的 Spring 存储库中是否有效,但它看起来并不像这样。

为了简单起见,我有一个 Repository 类:

@Repository
public class CustomerRepository {
    // Java client for Redis, that I extend as JedisConnector in order to make it a Bean
    private Jedis jedis;

    @Autowired
    public CustomerRepository(JedisConnector jedis) {
        this.jedis = jedis;
    }

    private <S extends Customer> S save(@Valid S customer) throws CustomerException {
        try {
            this.jedis.set(...);  // writing to Redis (mocked in test)
            return customer;
        } catch (JsonProcessingException e) {
            throw new CustomerException(e.toString());
        }
    }
}

这使用以下模型类:

@AllArgsConstructor
@NoArgsConstructor
@Data // from Lombok
public class Customer {
    @Email(message = "Email must be valid.")
    private String identifier;

    @NotBlank(message = "Password cannot be null or empty string.")
    private String password;

    @URL(message = "URL must be a url.")
    private String url;
}

所以我编写了一个像这样的单元测试,期望它抛出一些我可以断言的异常:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {JedisConnector.class})
public class CustomerRepositoryTest {
    // Cannot autowire because dependent bean needs to be configured
    private CustomerRepository customerRepository;

    @MockBean
    JedisConnector jedisConnector;

    @Before
    public void setUp() {
        // Configure Mock JedisConnector
        MockitoAnnotations.initMocks(this);
        Mockito.when(jedisConnector.select(anyInt())).thenReturn("OK");

        // Manually wire dependency
        customerRepository = new CustomerRepository(jedisConnector);
    }


    @Test
    public void saveShouldFailOnInvalidInput() throws CustomerException {
        Mockito.when(jedisConnector.set(anyString(), anyString())).thenReturn("OK");
        // Blatantly invalid input
        Customer customer = new Customer("testemail", "", "testurl");
        customerRepository.save(customer);
    }
}

但它只是运行,仅输出调试消息(我在这个问题中遗漏了)。 如何强制执行验证?如果可能,我希望避免在存储库的每个方法中显式调用 validator 。

我在网上看到了很多我试图重现的例子(从 Baeldung 到 DZone,当然这个网站上有很多问题,包括 this interesting one ),但仍然不成功。我错过了什么?

最佳答案

如果您想使用repository via,则似乎需要实现集成测试,以便抛出javax.validation.ConstraintViolationException显示不能为空,但如果您只想测试这些验证,那么您必须通过以下方式使用 validator 进行测试:

1.- 添加以下依赖项:

<dependency> 
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.13.Final</version>
</dependency> 

2.- 为 Customer 字段添加自定义验证测试

import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
public class CustomerValidationTest {

    private Validator validator;

    @Before
    public void setupValidatorInstance() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void whenNotEmptyPassword_thenNoConstraintViolations() {
        Customer customer = new Customer();
        customer.setPassword("");
        Set<ConstraintViolation<Customer>> violations = validator.validate(customer);

        assertThat(violations.size()).isEqualTo(1);
    }
}

关于java - @Valid不会触发@Repository中的验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58561337/

相关文章:

java - 为什么我在运行 Spring Boot 项目时总是收到状态为 “404” 的 Whitelabel 错误页面

java - List<E> 不喜欢我的自定义类

java - 如何通过索引获取 TreeMap 的键?

java - 如何从配置中设置 Enum

java - 实体更新导致错误: cascade ="all-delete-orphan" was no longer referenced by the owning entity

spring-boot - 带有 Spring 的 GraphQL-java - 解析器 vd datafetcher

java - 具有 Spring Boot 集成的 Cucumber Java - Spring @Autowired 抛出 NullPointer 异常

python - Django 测试在数据库创建时卡住

c++ - 如何使用(智能)指针指向模拟对象(在谷歌模拟中)

java提示+在获取字符串之前获取数字包含任何空格(一个或多个)