2023-04-20 목
오늘은 UserService에 대한 테스트를 진행해보았다.
service 부분은 컨트롤러와 직접적인 영향을 미치기 때문에 페이지 별로 해당하는 서비스를 생각해보고 테스트했다.
@Test
void 서비스isNotNull(){
Assertions.assertThat(userService).isNotNull();
}
가장 먼저 UserService 클래스를 만들어 유무를 확인하는 테스트를 진행했다.
// 회원가입 - 아이디 중복 체크 버튼
@Test
@Transactional
void signUp_duplicateId(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
UserEntity user1Entity = user1.toEntity();
userRepository.save(user1Entity);
//given
UserDto user2 = UserDto.builder()
.userId("yhw0104")
.userPassword("5678")
.userName("윤형우")
.userNickName("닉네임2")
.build();
int result = userService.checkDuplicateId(user2.getUserId());
//then
assertThat(result).isEqualTo(1);
}
해당 테스트는 아이디 중복에 대한 테스트다.
checkDuplicateId 메서드를 만들어 해당 서비스를 테스트 했다.
// 아이디 중복 체크 버튼 기능 (파라미터 -> 비교할 회원 아이디)
// 버튼 클릭시 ajax로 get방식으로 받아와서 중복 확인 리턴 값이 1이면 중복 0이면 사용가능 창 띄우기
// ajax 처리시 반환값 다시 생각해보기
public int checkDuplicateId(String userId) {
boolean trueOrFalse = userRepository.existsByUserId(userId);
if(trueOrFalse == true){
System.out.println("duplicate ID!!");
return 1;
}
else{
System.out.println("possible ID!!");
return 0;
}
이 서비스는 회원 가입 페이지에서 아이디 폼 옆에 버튼을 눌렀을 시 실행되는 메서드이다.
만약 반환 값이 1이면 아이디가 중복된다는 메시지를 띄우고, 0이면 아이디를 사용할 수 있다는 메시지를 띄우게 할 것이다.
// 회원가입 - 닉네임 중복 체크 버튼
@Test
@Transactional
void signUp_duplicateNickName(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("같은 닉네임")
.build();
UserEntity user1Entity = user1.toEntity();
userRepository.save(user1Entity);
//given
UserDto user2 = UserDto.builder()
.userId("0104yhw")
.userPassword("5678")
.userName("윤형우")
.userNickName("같은 닉네임")
.build();
int result = userService.checkDuplicateNickName(user2.getUserNickName());
//then
assertThat(result).isEqualTo(1);
}
닉네임 중복 테스트도 아이디 중복 테스트와 같은 방식이다.
checkDuplicatiieNickName 메서드를 만들어 테스트를 진행했다.
// 닉네임 중복 체크 버튼 기능 (파라미터 -> 비교할 닉네임)
// 버튼 클릭시 ajax로 get방식으로 받아와서 중복 확인 리턴 값이 1이면 중복 0이면 사용가능 창 띄우기
// ajax 처리시 반환값 다시 생각해보기
public int checkDuplicateNickName(String userNickName) {
boolean trueOrFalse = userRepository.existsByUserNickName(userNickName);
if(trueOrFalse == true){
System.out.println("duplicate NickName!!");
return 1;
}
else{
System.out.println("possible NickName!!");
return 0;
}
}
닉네임 중복 체크 서비스도 아이디 중복 체크 서비스와 같은 형식으로 코드를 짰다.
해당 메서드도 반환 값을 1과 0으로 받아 사용가능한 아이디인지 판별하게 한다.
// 회원가입 - 성공
@Test
@Transactional
void signUp_Success(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
UserEntity user1Entity = user1.toEntity();
userRepository.save(user1Entity);
//given
UserDto user2 = UserDto.builder()
.userId("0104yhw")
.userPassword("5678")
.userName("윤형우")
.userNickName("닉네임2")
.build();
int checkId = userService.checkDuplicateId(user2.getUserId());
int checkNickName = userService.checkDuplicateNickName(user2.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user2);
}
}
//then
assertThat(userRepository.findAll().size()).isEqualTo(2);
}
해당 테스트는 아이디, 닉네임 중복 체크를 받아 사용가능한 아이디와 닉네임일 때 회원정보를 저장하는 테스트이다.
if(checkId == 0){
if(checkNickName == 0){
userService.save(user2);
}
}
이 if문이 해당 반환값이 둘다 0일때 저장하게 만들어 아이디, 닉네임 중복을 확인해준다.
// 회원가입 (회원가입 성공)
// 아이디, 닉네임 중복 체크 확인 후 저장 할 수 있도록 수정해야함
public UserEntity save(UserDto userDto) {
UserEntity entity = userDto.toEntity();
userRepository.save(entity);
return entity;
}
회원정보 저장 메서드는 DTO로 받아온 데이터를 Entity로 변환후 저장하는 로직을 가졌다.
// 아이디 찾기 (이름과 전화번호)
@Test
@Transactional
void findUserId(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
// 아이디 닉네임 중복 검사
int checkId = userService.checkDuplicateId(user1.getUserId());
int checkNickName = userService.checkDuplicateNickName(user1.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user1);
}
}
//given
// 아이디 찾기 페이지에서 들어온 이름과 전화번호 값
String user1Name = user1.getUserName();
String user1PhoneNumber = user1.getUserPhoneNumber();
String expected = userService.findId(user1Name, user1PhoneNumber);
//then
assertThat(user1.getUserId()).isEqualTo(expected);
}
아이디 찾기 메서드는 파라미터를 이름과 전화번호를 입력해 해당 아이디 값을 반환하는 메서드이다.
// 아이디 찾기 (이름과 전화번호)
public String findId(String userName, String userPhoneNumber) {
Optional<UserEntity> findId = userRepository.findByUserNameAndUserPhoneNumber(userName, userPhoneNumber);
String id = findId.get().getUserId();
return id;
}
userRepository의 findByUserNameAndUserPhoneNumber메서드를 사용하여 해당하는 이름과 전화번호를 가지는 데이터를 반환시킨다.
// 비밀번호 찾기 (아이디와 이름)
@Test
@Transactional
void findUserPassword(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
// 아이디 닉네임 중복 검사
int checkId = userService.checkDuplicateId(user1.getUserId());
int checkNickName = userService.checkDuplicateNickName(user1.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user1);
}
}
//given
String user1Id = user1.getUserId();
String user1Name = user1.getUserName();
Optional<UserEntity> expected = userService.findPassword(user1Id, user1Name);
//then
assertThat(expected.get().getUserIndex()).isEqualTo(1L);
assertThat(user1.getUserId()).isEqualTo(expected.get().getUserId());
assertThat(user1.getUserName()).isEqualTo(expected.get().getUserName());
assertThat(user1.getUserNickName()).isEqualTo(expected.get().getUserNickName());
assertThat(user1.getUserPassword()).isEqualTo(expected.get().getUserPassword());
assertThat(user1.getUserPhoneNumber()).isEqualTo(expected.get().getUserPhoneNumber());
}
비밀번호를 까먹으면 대부분의 웹페이지에서는 새로운 비밀번호로 변경하게 해준다.
그래서 페이지를 생각해 보았을 때,
비밀번호 찾기 버튼 클릭 -> 아이디와 이름 입력 페이지 -> 비밀번호 변경 페이지
이렇게 3부분으로 나뉜다.
그래서 이 테스트는 아이디와 이름 입력 페이지에서 아이디와 이름을 입력 받으면 해당 데이터를 받아오고 비밀번호 변경 페이지에서 비밀번호를 수정하기 때문에 해당 데이터를 가져오는 서비스와 변경하는 서비스로 두개로 나누었다.
// 비밀번호 찾기(아이디와 이름)
// 비밀번호 찾기 페이지에서 필요한 데이터 입력 후
public Optional<UserEntity> findPassword(String userId, String userName) {
Optional<UserEntity> findPassword = userRepository.findByUserIdAndUserName(userId, userName);
return findPassword;
}
그래서 아이디와 이름을 파라미터로 받을 때 해당 데이터를 반환하는 서비스 코드를 작성했다.
// 비밀번호 변경
@Test
@Transactional
void changeUserPassword(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
// 아이디 닉네임 중복 검사
int checkId = userService.checkDuplicateId(user1.getUserId());
int checkNickName = userService.checkDuplicateNickName(user1.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user1);
}
}
//given
String user1Id = user1.getUserId();
String user1Name = user1.getUserName();
Optional<UserEntity> findInfo = userService.findPassword(user1Id, user1Name);
String changePassword = "5678";
Optional<UserEntity> expected = userService.changePassword(findInfo, changePassword);
//then
assertThat(findInfo.get().getUserId()).isEqualTo(expected.get().getUserId());
assertThat(findInfo.get().getUserName()).isEqualTo(expected.get().getUserName());
assertThat(findInfo.get().getUserNickName()).isEqualTo(expected.get().getUserNickName());
assertThat(findInfo.get().getUserPassword()).isEqualTo(changePassword);
assertThat(findInfo.get().getUserPhoneNumber()).isEqualTo(expected.get().getUserPhoneNumber());
}
비밀번호 찾기 페이지에서 받아온 데이터로 비밀번호를 변경하는 테스트이다.
changePasssword 서비스 메서드로 비밀번호를 변경한다.
// 비밀번호 변경
// 비밀번호를 바꿀 회원정보를 찾은 후 변경하는 페이지때 사용
// 파라미터 변경 생각해보기
public Optional<UserEntity> changePassword(Optional<UserEntity> findInfo, String changePassword) {
findInfo.map(p -> {
findInfo.get().setUserPassword(changePassword);
return p;
})
.map(p -> userRepository.save(p));
return findInfo;
}
아직 컨트롤러 부분을 만들지 않았기 때문에 해당 서비스 로직의 파라미터는 좀 더 생각해봐야 할 것 같다.
// 회원정보 보기
@Test
@Transactional
void getUserInfo() {
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
// 아이디 닉네임 중복 검사
int checkId = userService.checkDuplicateId(user1.getUserId());
int checkNickName = userService.checkDuplicateNickName(user1.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user1);
}
}
Optional<UserEntity> user = userRepository.findById(1L);
//given
Optional<UserEntity> expected = userService.findUserInfo(1L);
//then
assertThat(user.get().getUserId()).isEqualTo(expected.get().getUserId());
assertThat(user.get().getUserName()).isEqualTo(expected.get().getUserName());
assertThat(user.get().getUserNickName()).isEqualTo(expected.get().getUserNickName());
assertThat(user.get().getUserPhoneNumber()).isEqualTo(expected.get().getUserPhoneNumber());
}
findUserInfo 메서드를 만들어 로그인 후 해당 로그인이 된 데이터의 id값을 파라미터로 받아 회원정보를 볼 수 있게 만들었다.
// 회원정보 보기
public Optional<UserEntity> findUserInfo(Long userIndex) {
Optional<UserEntity> findUser = userRepository.findById(userIndex);
return findUser;
}
// 회원정보 수정
@Test
@Transactional
void updateUserInfo(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
// 아이디 닉네임 중복 검사
int checkId = userService.checkDuplicateId(user1.getUserId());
int checkNickName = userService.checkDuplicateNickName(user1.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user1);
}
}
Optional<UserEntity> user = userRepository.findById(1L);
//given
userService.changeUserInfo(user);
//then
assertThat(user.get().getUserName()).isEqualTo("윤하연");
assertThat(user.get().getUserNickName()).isEqualTo("윤공주");
assertThat(user.get().getUserPhoneNumber()).isEqualTo("01093195367");
}
회원정보 수정 테스트는 해당 데이터를 받아와 changeUserInfo 메서드로 이름, 닉네임, 전화번호를 변경할 수 있게끔 만들었다.
public Optional<UserEntity> changeUserInfo(Optional<UserEntity> user) {
user.map(p -> {
user.get().setUserName("윤하연");
user.get().setUserNickName("윤공주");
user.get().setUserPhoneNumber("01093195367");
return p;
})
.map(p -> userRepository.save(p));
return user;
}
아이디, 비밀번호는 변경할 수 없다.
// 회원 탈퇴
@Test
@Transactional
void deleteUserInfo(){
//when
UserDto user1 = UserDto.builder()
.userId("yhw0104")
.userPassword("1234")
.userName("윤현우")
.userNickName("닉네임1")
.build();
// 아이디 닉네임 중복 검사
int checkId = userService.checkDuplicateId(user1.getUserId());
int checkNickName = userService.checkDuplicateNickName(user1.getUserNickName());
if(checkId == 0){
if(checkNickName == 0){
userService.save(user1);
}
}
//given
userService.deleteUserInfo(1L);
List<UserEntity> expected = userRepository.findAll();
//then
assertThat(expected.size()).isEqualTo(0);
}
회원 탈퇴 테스트는 JpaRepository의 deleteBy~메서드를 사용하면 되기 때문에 비교적 간단하게 끝냈다.
public void deleteUserInfo(Long userIndex) {
userRepository.deleteById(userIndex);
}
어제 레파지토리 테스트는 페이지 별 필요한 서비스를 생각하지 않고 테스트를 진행했다.
하지만 서비스 테스트는 페이지 별로 나누어 서비스가 동작해야하기 때문에 그걸 생각하며 코드를 작성했다.
오늘 느낀 것은 코드를 짤때 이전보다 많이 생각하며 짜게 되는 것 같아 더욱 공부가 잘되는것 같다.
그리고 하나의 프로덕트를 만드는 것이 생각보다 많은 시간과 공을 들여 만드는 것임을 생각했다.
앞으로도 더욱 열심히 공부해서 모르는것이 없는 멋진 개발자가 되고싶다.