Member라는 엔티티에서 이루어지는 도메인 로직에 대한 테스트들을 만들었다. 이 테스트를 정상적으로 수행하기 위한 코드를 만들어보아야 겠다.
Member라는 도메인 로직을 짜면서 추가적으로 고민했던 부분은,
- 다른 도메인과 엮여 사용되어 다른 도메인, 다른 기능에 종속적이지 않게 하려고 했다.
- 외부에서 Member에 대한 데이터를 변경하는 기능을 수행하는 경우를 만들지 않도록, 도메인 내에서 모든 로직을 만들려고 했다.
이러한 점을 토대로, 회원가입 / 정보 수정 / 비밀번호 변경 기간 만기여부 확인의 기능을 만들었다.
회원가입
일단 회원가입 로직부터 정리를 해보았다.
일단 필요한 경우는
- 이메일 형식이 올바르지 않으면 예외처리
- 비밀번호 2번 입력이 서로 일치하지 않으면 예외처리
- 예외가 없다면 인스턴스 초기화 시켜 Member 생성해준다.
여기에서 중복을 확인하지 않은 이유는, 데이터베이스에서 중복 여부를 확인하고 예외처리하는 기능은
Member라는 도메인에서 동작하기보단, 레포지토리를 이용하는 서비스에서 처리하는 것이 더 나을 것 같다는 생각이 들었기 때문이다.
public Member(RegisterRequestDto registerRequestDto){
if(isEmailNotFormat(registerRequestDto.getEmail())) throw new EmailNotFormatException();
if(isPasswordNotSame(registerRequestDto.getPassword(), registerRequestDto.getPasswordCheck()))
throw new PasswordNotMatchingException();
this.username = registerRequestDto.getUsername();
this.nickname = registerRequestDto.getNickname();
this.email = registerRequestDto.getEmail();
this.role = Role.USER;
this.password = registerRequestDto.getPassword();
this.setLastModifiedDate(LocalDateTime.now());
}
이런 방식으로 메서드가 구현되었다.
닉네임 변경
닉네임 변경같은 경우에는, 특정 문자를 사용하지 못하게 하는 등의 문제가 없게 할 계획이었기 때문에, 이전 본인의 닉네임과 동일한 경우만을 제외하면 언제든 변경할 수 있게 설정해두었다.
public void changeNickname(ChangeNicknameRequestDto changeNicknameRequestDto){
if(isNicknameSameWithFormal(changeNicknameRequestDto)) throw new NicknameAlreadyInUseException();
this.nickname = changeNicknameRequestDto.getNewNickname();
}
private boolean isNicknameSameWithFormal(ChangeNicknameRequestDto changeNicknameRequestDto){
return this.nickname.equals(changeNicknameRequestDto.getNewNickname());
}
이메일 변경
이메일은 닉네임과 비교했을 때 하나의 경우가 더 존재한다. 이메일 형식이 올바르지 않을 때
그렇기 때문에 정규식을 이용한 비교를 한번 더 해서 이에 대한 예외를 추가해주었다.
public void changeEmail(ChangeEmailRequestDto changeEmailRequestDto){
if(isEmailNotFormat(changeEmailRequestDto.getNewEmail())) throw new EmailNotFormatException();
if(isEmailSameWithFormal(changeEmailRequestDto)) throw new EmailAlreadyInUseException();
this.email = changeEmailRequestDto.getNewEmail();
}
private boolean isEmailSameWithFormal(ChangeEmailRequestDto changeEmailRequestDto){
return this.email.equals(changeEmailRequestDto.getNewEmail());
}
private boolean isEmailNotFormat(String email){
return !Pattern.matches("^[_a-z0-9-]+(.[_a-z0-9-]+)*@(?:\\w+\\.)+\\w+$", email);
}
비밀번호 변경
비밀번호를 작성할 때에는 비밀번호, 비밀번호확인까지 총 2개의 입력이 존재하며, 이 둘이 같아야 한다.
2개의 비밀번호가 다를 경우, 그리고 기존 비밀번호와 변경하려는 비밀번호가 같을 때 예외처리 시켜주었다.
public void changePassword(ChangePasswordRequestDto changePasswordRequestDto){
if(isPasswordNotSame(changePasswordRequestDto.getNewPassword(), changePasswordRequestDto.getNewPasswordCheck()))
throw new PasswordNotMatchingException();
if(isPasswordSameWithFormal(changePasswordRequestDto.getNewPassword()))
throw new PasswordNotChangedException();
this.password = changePasswordRequestDto.getNewPassword();
this.setLastModifiedDate(LocalDateTime.now());
}
private boolean isPasswordNotSame(String pw1, String pw2){
return !pw1.equals(pw2);
}
private boolean isPasswordSameWithFormal(String pw1){
return this.password.equals(pw1);
}
비밀번호 변경기간 만료 여부 확인
이 부분을 위해서 baseEntity에 메서드를 추가하고, enum 클래스를 생성해주었다.
public boolean isLastModifiedDateAfter(Long days){
return LocalDateTime.now().minusDays(days).isAfter(this.lastModifiedDate);
}
일단 BaseEntity에 이런 메서드가 추가되었다. 비밀번호 외적으로도, 나중에 사용할 때 하나의 메서드를 호출해 이 기능을 사용하기 위해
입력변수로 받은 날짜만큼을 현재에서 뺐을 때, 그 날짜가 최종 수정일자보다 지났으면 참을 반환하게 만들었다.
package com.board.Board_Upgraded.entity.base;
public enum DueTime {
PASSWORD_CHANGE_DUETIME(30L);
private Long days;
private DueTime(Long days){
this.days = days;
}
public Long getDays(){
return this.days;
}
}
이후에 DueTime이라는 enum 클래스를 만들어서, 비밀번호 변경 주기를 한달로 가정하고 만들었다.
public boolean isPasswordOutdated(){
return isLastModifiedDateAfter(DueTime.PASSWORD_CHANGE_DUETIME.getDays());
}
이후에 이렇게, 비밀번호가 만료되었는지를 이전의 메서드에 enum클래스의 비밀번호 변경주기를 받아와 비교하게 시켰다.
테스트를 전부 통과하게 만들기는 했다.
이제 레포지토리 구현 후, 서비스를 만들고 진행해야 한다.
서비스를 테스트하는 방법을 공부해보고, 이에 대해서도 포스팅해야겠다.
'스프링 공부 > 게시판 프로젝트 만들기' 카테고리의 다른 글
[스프링] 17. MemberRepository 테스트해보기 (0) | 2023.02.02 |
---|---|
[스프링] 16. MemberRepository 만들기 (0) | 2023.02.02 |
[스프링] 14. Member에 대한 테스트 만들기 (0) | 2023.01.11 |
[스프링] 13. Member 엔티티 만들기 (0) | 2023.01.11 |
[스프링] 12. Member 엔티티에 대해 생각해보기 (0) | 2023.01.11 |