Spring Boot Bean Validation example
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.Pattern;
|
||||
|
||||
@Entity
|
||||
public class Input {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@Min(1)
|
||||
@Max(10)
|
||||
private int numberBetweenOneAndTen;
|
||||
|
||||
// Note that this is actually not a valid IP address pattern, since
|
||||
// it allows values greater than 255 per octet.
|
||||
@Pattern(regexp = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$")
|
||||
private String ipAddress;
|
||||
|
||||
public int getNumberBetweenOneAndTen() {
|
||||
return numberBetweenOneAndTen;
|
||||
}
|
||||
|
||||
public void setNumberBetweenOneAndTen(int numberBetweenOneAndTen) {
|
||||
this.numberBetweenOneAndTen = numberBetweenOneAndTen;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Null;
|
||||
|
||||
import io.reflectoring.validation.service.OnCreate;
|
||||
import io.reflectoring.validation.service.OnUpdate;
|
||||
|
||||
@Entity
|
||||
public class InputWithCustomValidator {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@NotNull(groups = OnUpdate.class)
|
||||
@Null(groups = OnCreate.class)
|
||||
private Long id;
|
||||
|
||||
@Min(1)
|
||||
@Max(10)
|
||||
@Column
|
||||
private int numberBetweenOneAndTen;
|
||||
|
||||
@IpAddress
|
||||
@Column
|
||||
private String ipAddress;
|
||||
|
||||
public int getNumberBetweenOneAndTen() {
|
||||
return numberBetweenOneAndTen;
|
||||
}
|
||||
|
||||
public void setNumberBetweenOneAndTen(int numberBetweenOneAndTen) {
|
||||
this.numberBetweenOneAndTen = numberBetweenOneAndTen;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Target({ FIELD })
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = IpAddressValidator.class)
|
||||
@Documented
|
||||
public @interface IpAddress {
|
||||
|
||||
String message() default "{IpAddress.invalid}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class IpAddressValidator implements ConstraintValidator<IpAddress, String> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
Pattern pattern = Pattern.compile("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$");
|
||||
Matcher matcher = pattern.matcher(value);
|
||||
try {
|
||||
if (!matcher.matches()) {
|
||||
return false;
|
||||
} else {
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
int octet = Integer.valueOf(matcher.group(i));
|
||||
if (octet > 255) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ValidationApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ValidationApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.reflectoring.validation.controller.controlleradvice;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ControllerAdvice
|
||||
class ErrorHandlingControllerAdvice {
|
||||
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ResponseBody
|
||||
ValidationErrorResponse onConstraintValidationException(ConstraintViolationException e) {
|
||||
ValidationErrorResponse error = new ValidationErrorResponse();
|
||||
for (ConstraintViolation violation : e.getConstraintViolations()) {
|
||||
error.getViolations().add(new Violation(violation.getPropertyPath().toString(), violation.getMessage()));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ResponseBody
|
||||
ValidationErrorResponse onMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
ValidationErrorResponse error = new ValidationErrorResponse();
|
||||
for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
|
||||
error.getViolations().add(new Violation(fieldError.getField(), fieldError.getDefaultMessage()));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.reflectoring.validation.controller.controlleradvice;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ValidationErrorResponse {
|
||||
|
||||
private List<Violation> violations = new ArrayList<>();
|
||||
|
||||
public List<Violation> getViolations() {
|
||||
return violations;
|
||||
}
|
||||
|
||||
public void setViolations(List<Violation> violations) {
|
||||
this.violations = violations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.reflectoring.validation.controller.controlleradvice;
|
||||
|
||||
public class Violation {
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
private final String message;
|
||||
|
||||
public Violation(String fieldName, String message) {
|
||||
this.fieldName = fieldName;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.reflectoring.validation.repository;
|
||||
|
||||
import io.reflectoring.validation.Input;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface ValidatingRepository extends CrudRepository<Input, Long> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.reflectoring.validation.repository;
|
||||
|
||||
import io.reflectoring.validation.InputWithCustomValidator;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface ValidatingRepositoryWithCustomValidator extends CrudRepository<InputWithCustomValidator, Long> {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
public interface OnCreate {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
public interface OnUpdate {
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import io.reflectoring.validation.Input;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ProgrammaticallyValidatingService {
|
||||
|
||||
private Validator validator;
|
||||
|
||||
public ProgrammaticallyValidatingService(Validator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public void validateInput(Input input) {
|
||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||
Validator validator = factory.getValidator();
|
||||
Set<ConstraintViolation<Input>> violations = validator.validate(input);
|
||||
if (!violations.isEmpty()) {
|
||||
throw new ConstraintViolationException(violations);
|
||||
}
|
||||
}
|
||||
|
||||
public void validateInputWithInjectedValidator(Input input) {
|
||||
Set<ConstraintViolation<Input>> violations = validator.validate(input);
|
||||
if (!violations.isEmpty()) {
|
||||
throw new ConstraintViolationException(violations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import io.reflectoring.validation.Input;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
class ValidatingService {
|
||||
|
||||
void validateInput(@Valid Input input){
|
||||
// do something
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import io.reflectoring.validation.InputWithCustomValidator;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
class ValidatingServiceWithGroups {
|
||||
|
||||
@Validated(OnCreate.class)
|
||||
void validateForCreate(@Valid InputWithCustomValidator input){
|
||||
// do something
|
||||
}
|
||||
|
||||
@Validated(OnUpdate.class)
|
||||
void validateForUpdate(@Valid InputWithCustomValidator input){
|
||||
// do something
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
IpAddress.invalid=Invalid IP Address: "${validatedValue}"!
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class IpAddressValidatorTest {
|
||||
|
||||
@Test
|
||||
void test(){
|
||||
IpAddressValidator validator = new IpAddressValidator();
|
||||
assertTrue(validator.isValid("111.111.111.111", null));
|
||||
assertFalse(validator.isValid("111.foo.111.111", null));
|
||||
assertFalse(validator.isValid("111.111.256.111", null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import io.reflectoring.validation.service.ProgrammaticallyValidatingService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest
|
||||
class ProgrammaticallyValidatingServiceTest {
|
||||
|
||||
@Autowired
|
||||
private ProgrammaticallyValidatingService service;
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalid_thenThrowsException(){
|
||||
Input input = new Input();
|
||||
input.setNumberBetweenOneAndTen(0);
|
||||
input.setIpAddress("invalid");
|
||||
|
||||
assertThrows(ConstraintViolationException.class, () -> {
|
||||
service.validateInput(input);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInjectedValidator_whenInputIsInvalid_thenThrowsException(){
|
||||
Input input = new Input();
|
||||
input.setNumberBetweenOneAndTen(0);
|
||||
input.setIpAddress("invalid");
|
||||
|
||||
assertThrows(ConstraintViolationException.class, () -> {
|
||||
service.validateInputWithInjectedValidator(input);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.reflectoring.validation;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class ValidationApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.reflectoring.validation.controller.parameters;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebMvcTest(controllers = ValidateParametersController.class)
|
||||
class ValidateParametersControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
|
||||
@Test
|
||||
void whenPathVariableIsInvalid_thenReturnsStatus400() throws Exception {
|
||||
mvc.perform(get("/validatePathVariable/3"))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenRequestParameterIsInvalid_thenReturnsStatus400() throws Exception {
|
||||
mvc.perform(get("/validateRequestParameter")
|
||||
.param("param", "3"))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPathVariableIsValid_thenReturnsStatus200() throws Exception {
|
||||
mvc.perform(get("/validatePathVariable/10"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package io.reflectoring.validation.controller.requestbody;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.reflectoring.validation.Input;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebMvcTest(controllers = ValidateRequestBodyController.class)
|
||||
class ValidateRequestBodyControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalid_thenReturnsStatus400() throws Exception {
|
||||
Input input = invalidInput();
|
||||
String body = objectMapper.writeValueAsString(input);
|
||||
|
||||
mvc.perform(post("/validateBody")
|
||||
.contentType("application/json")
|
||||
.content(body))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
private Input invalidInput() {
|
||||
Input input = new Input();
|
||||
input.setIpAddress("invalid");
|
||||
input.setNumberBetweenOneAndTen(99);
|
||||
return input;
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalid_thenReturnsStatus400WithErrorObject() throws Exception {
|
||||
Input input = invalidInput();
|
||||
String body = objectMapper.writeValueAsString(input);
|
||||
|
||||
MvcResult result = mvc.perform(post("/validateBody")
|
||||
.contentType("application/json")
|
||||
.content(body))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andReturn();
|
||||
|
||||
assertThat(result.getResponse().getContentAsString()).contains("violations");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInputIsValid_thenReturnsStatus200() throws Exception {
|
||||
Input input = validInput();
|
||||
String body = objectMapper.writeValueAsString(input);
|
||||
|
||||
mvc.perform(post("/validateBody")
|
||||
.contentType("application/json")
|
||||
.content(body))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
private Input validInput() {
|
||||
Input input = new Input();
|
||||
input.setIpAddress("255.255.255.255");
|
||||
input.setNumberBetweenOneAndTen(10);
|
||||
return input;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.reflectoring.validation.repository;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import io.reflectoring.validation.Input;
|
||||
import io.reflectoring.validation.repository.ValidatingRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@DataJpaTest
|
||||
class ValidatingRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private ValidatingRepository repository;
|
||||
|
||||
@Autowired
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalid_thenThrowsException() {
|
||||
Input input = invalidInput();
|
||||
|
||||
assertThrows(ConstraintViolationException.class, () -> {
|
||||
repository.save(input);
|
||||
entityManager.flush();
|
||||
});
|
||||
}
|
||||
|
||||
private Input invalidInput() {
|
||||
Input input = new Input();
|
||||
input.setNumberBetweenOneAndTen(0);
|
||||
input.setIpAddress("invalid");
|
||||
return input;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package io.reflectoring.validation.repository;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import io.reflectoring.validation.InputWithCustomValidator;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@DataJpaTest
|
||||
class ValidatingRepositoryWithCustomValidatorTest {
|
||||
|
||||
@Autowired
|
||||
private ValidatingRepositoryWithCustomValidator repository;
|
||||
|
||||
@Autowired
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalid_thenThrowsException() {
|
||||
InputWithCustomValidator input = invalidInput();
|
||||
try {
|
||||
repository.save(input);
|
||||
entityManager.flush();
|
||||
Assertions.fail("expected ConstraintViolationException");
|
||||
} catch (ConstraintViolationException e) {
|
||||
assertThat(e.getConstraintViolations()).hasSize(2);
|
||||
}
|
||||
}
|
||||
|
||||
private InputWithCustomValidator invalidInput() {
|
||||
InputWithCustomValidator input = new InputWithCustomValidator();
|
||||
input.setNumberBetweenOneAndTen(0);
|
||||
input.setIpAddress("invalid");
|
||||
return input;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import io.reflectoring.validation.Input;
|
||||
import io.reflectoring.validation.service.ValidatingService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest
|
||||
class ValidatingServiceTest {
|
||||
|
||||
@Autowired
|
||||
private ValidatingService service;
|
||||
|
||||
@Test
|
||||
void whenInputIsValid_thenThrowsNoException(){
|
||||
Input input = new Input();
|
||||
input.setNumberBetweenOneAndTen(5);
|
||||
input.setIpAddress("111.111.111.111");
|
||||
|
||||
service.validateInput(input);
|
||||
|
||||
// then no exception
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalid_thenThrowsException(){
|
||||
Input input = new Input();
|
||||
input.setNumberBetweenOneAndTen(0);
|
||||
input.setIpAddress("invalid");
|
||||
|
||||
assertThrows(ConstraintViolationException.class, () -> {
|
||||
service.validateInput(input);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package io.reflectoring.validation.service;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import io.reflectoring.validation.InputWithCustomValidator;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest
|
||||
class ValidatingServiceWithGroupsTest {
|
||||
|
||||
@Autowired
|
||||
private ValidatingServiceWithGroups service;
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalidForCreate_thenThrowsException() {
|
||||
InputWithCustomValidator input = validInput();
|
||||
input.setId(42L);
|
||||
assertThrows(ConstraintViolationException.class, () -> {
|
||||
service.validateForCreate(input);
|
||||
});
|
||||
}
|
||||
|
||||
private InputWithCustomValidator validInput() {
|
||||
InputWithCustomValidator input = new InputWithCustomValidator();
|
||||
input.setNumberBetweenOneAndTen(1);
|
||||
input.setIpAddress("111.111.111.111");
|
||||
return input;
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInputIsInvalidForUpdate_thenThrowsException() {
|
||||
InputWithCustomValidator input = validInput();
|
||||
input.setId(null);
|
||||
assertThrows(ConstraintViolationException.class, () -> {
|
||||
service.validateForUpdate(input);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user