✅ POJO 테스트
▸ POJO 란?
▸ POJO 테스트란?
✅ UserRequestDto 테스트
▸ CommonTest
▸ UserRequestDtoTest
✅ ConstraintViolation
▸ ConstraintViolation의 method
✅ ReflextionTestUtils
▸ ReflextionTestUtils의 method
▸ POJO 테스트
▸ @Valid 테스트
▸ ConstraintViolation
▸ ReflextionTestUtils
@Getter
public class UserRequsetDto {
@NotBlank(message = "username을 입력하세요.")
@Pattern(regexp = "^[a-z0-9]{4,10}$", message = "a-z, 0-9, 글자길이 4-10")
private String username;
@NotBlank(message = "password를 입력하세요.")
@Pattern(regexp = "^[a-zA-Z0-9]{8,15}$", message = "a-z, A-z, 0-9, 글자길이 8-15")
private String password;
}
public interface CommonTest {
String ANOTHER_PREFIX = "another-";
Long TEST_USER_ID = 1L;
Long TEST_ANOTHER_USER_ID = 2L;
String TEST_USER_NAME = "username";
String TEST_USER_PASSWORD = "password";
User TEST_USER = User.builder()
.username(TEST_USER_NAME)
.password(TEST_USER_PASSWORD)
.build();
User TEST_ANOTHER_USER = User.builder()
.username(ANOTHER_PREFIX + TEST_USER_NAME)
.password(ANOTHER_PREFIX + TEST_USER_PASSWORD)
.build();
}
//builder를 사용하기 위해서는 UserEntity의 생성자에 @Builder가 적용되어야 한다.
@Builder
public User(String username, String password){
this.username = username;
this.password = password;
}
private <T> void setDto(T dto, String username, String password) {
ReflectionTestUtils.setField(dto, "username", username);
ReflectionTestUtils.setField(dto, "password", password);
}
@Valid와 같은 기능을 테스트 코드에서 구현하기 위해 validate 메서드를 만들었다.
private Set<ConstraintViolation<UserRequsetDto>> validate(UserRequsetDto userRequestDTO) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
return validator.validate(userRequestDTO);
}
ConstraintViolation -> 예외가 발생했다면 메세지 값을 조회할 수 있게 -> getMessage
public class UserRequestDtoTest implements CommonTest {
private <T> void setDto(T dto, String username, String password) {
ReflectionTestUtils.setField(dto, "username", username);
ReflectionTestUtils.setField(dto, "password", password);
}
@Nested
class 유저_요청_DTO_생성_테스트 {
@Test
void 생성_성공() {
// given
UserRequsetDto userRequsetDto = new UserRequsetDto();
setDto(userRequsetDto, TEST_USER_NAME, TEST_USER_PASSWORD);
// when
Set<ConstraintViolation<UserRequsetDto>> violations = validate(userRequsetDto);
// then
assertThat(violations).isEmpty();
//비어있으면 아무것도 잘못된게 없음 -> 정상적으로 UserRequestDto를 생성함
}
@Test
void 생성_실패_잘못된_username() {
// given
UserRequsetDto userRequsetDto = new UserRequsetDto();
setDto(userRequsetDto, "Invalid user name", TEST_USER_PASSWORD);
// when
Set<ConstraintViolation<UserRequsetDto>> violations = validate(userRequsetDto);
// then
assertThat(violations).hasSize(1); // 몇개 틀렸는지 hasSize
assertThat(violations)
.extracting("message") //"message"에 있는 값을 뽑아 올 때, extracting
.contains("a-z, 0-9, 글자길이 4-10");
}
@Test
void 생성_실패_null_username() {
// given
UserRequsetDto userRequsetDto = new UserRequsetDto();
setDto(userRequsetDto, " ", TEST_USER_PASSWORD);
// when
Set<ConstraintViolation<UserRequsetDto>> violations = validate(userRequsetDto);
// then
assertThat(violations).hasSize(2); // 몇개 틀렸는지 hasSize
assertThat(violations)
.extracting("message") //"message"에 있는 값을 뽑아 올 때, extracting
.contains("username을 입력하세요.");
}
@Test
void 생성_실패_잘못된_password() {
// given
UserRequsetDto userRequsetDto = new UserRequsetDto();
setDto(userRequsetDto, TEST_USER_NAME, "password!");
// when
Set<ConstraintViolation<UserRequsetDto>> violations = validate(userRequsetDto);
// then
assertThat(violations).hasSize(1); // 몇개 틀렸는지 hasSize
assertThat(violations)
.extracting("message") //"message"에 있는 값을 뽑아 올 때, extracting
.contains("a-z, A-z, 0-9, 글자길이 8-15");
}
@Test
void 생성_실패_null_password() {
// given
UserRequsetDto userRequsetDto = new UserRequsetDto();
setDto(userRequsetDto, TEST_USER_NAME, " ");
// when
Set<ConstraintViolation<UserRequsetDto>> violations = validate(userRequsetDto);
// then
assertThat(violations).hasSize(2); // 몇개 틀렸는지 hasSize
assertThat(violations)
.extracting("message") //"message"에 있는 값을 뽑아 올 때, extracting
.contains("password를 입력하세요.");
}
}
private Set<ConstraintViolation<UserRequsetDto>> validate(UserRequsetDto userRequestDTO) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
return validator.validate(userRequestDTO);
}
}
타입 | 메서드 | 반환 |
---|---|---|
String | getMessage() | 유효성 검사에 실패한 항목에 대한 오류 메시지를 반환합니다. |
Object | getInvalidValue() | 유효성 검사에 실패한 항목의 값을 반환합니다. |
Path | getPropertyPath() | 유효성 검사에 실패한 속성의 경로를 반환합니다. |
메서드 | 설명 |
---|---|
setField(Object target, String name, Object value) | 지정된 객체(target)의 필드(name)에 값을 설정한다. |
getField(Object target, String name) | 지정된 객체(target)의 필드(name)의 값을 반환한다. |
invokeMethod(Object target, String name, Object... args) | 지정된 객체(target)의 메서드(name)를 호출한다. |
private <T> void setDto(T dto, String username, String password) {
ReflectionTestUtils.setField(dto, "username", username);
ReflectionTestUtils.setField(dto, "password", password);
}
// given
UserRequsetDto userRequsetDto = new UserRequsetDto();
etDto(userRequsetDto, TEST_USER_NAME, TEST_USER_PASSWORD);