有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

为了简单起见,我有一个存储库类:

@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);
    }
}

但它只是运行,只输出调试消息(我在这个问题中漏掉了)如何执行验证如果可能的话,我希望避免在存储库的每个方法中明确地调用验证器

我在网上看到了许多我试图复制的例子(从贝尔东到佐内,当然在这个网站上有很多问题,包括this interesting one),但仍然没有成功。我错过了什么


共 (1) 个答案

  1. # 1 楼答案

    如果你想使用repositoryvia,那么你需要实现一个integration test,这样javax.validation.ConstraintViolationException就会通过显示must not be blank来抛出。但是如果你只想测试那些验证,那么你必须通过以下方式使用验证程序进行测试:

    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);
        }
    }