UserService에서는 로그인과 회원가입기능 처리하는 메서드가 구현되어 있는 상태이다.
UserService
-join
-login
이전에 Controller 에서는 Exception 발생하여 HttpStatus 에러 코드가 사용자가 정의한대로 왔는지를 체크하였고, Service단에서 현재 로직에서는 회원가입, 로그인 성공 / 예외로 인한 실패(exception) 만 존재하므로,
when() mocking 메서드로 발생할 수 있는 상황 경우의 수에 따른 케이스를 테스트코드에 정의하고, 각 경우의 수에 따라 발생하는 결과 확인하는 검증 코드 넣어서 테스트 작성한다.
Assertions.assertDoesNotThrow(()->userService.join(userName, password));
SnsApplicationException e = Assertions.assertThrows(SnsApplicationException.class, ()->userService.join(userName, password));
Assertions.assertEquals(ErrorCode.DUPLICATED_USER_NAME, e.getErrorCode());
아래는 UserService의 테스트 작성 예시 코드이다.
package com.example.sns.service;
import com.example.sns.exception.ErrorCode;
import com.example.sns.exception.SnsApplicationException;
import com.example.sns.fixture.UserEntityFixture;
import com.example.sns.model.entity.UserEntity;
import com.example.sns.repository.UserEntityRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Optional;
import static org.mockito.Mockito.when;
@SpringBootTest
public class UserServiceTest{
@Autowired
private UserService userService;
@MockBean
private UserEntityRepository userEntityRepository;
@MockBean
private BCryptPasswordEncoder encoder;
// 회원가입 성공
@Test
void 회원가입_성공(){
String userName = "userName";
String password = "password";
// 동일 userName 회원 존재하지 않음
when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.empty());
// save() 어떤 파라메터로든 호출 시 사용자가 정의한 UserEntity return하도록 정의
when(userEntityRepository.save(Mockito.any())).thenReturn(UserEntityFixture.get(userName, password));
Assertions.assertDoesNotThrow(()->userService.join(userName, password));
}
// 회원가입 실패 이미 존재하는 계정명
@Test
void 회원가입_실패_이미_존재하는_계정명(){
String userName = "userName";
String password = "password";
UserEntity fixture = UserEntityFixture.get(userName, password);
// 동일 userName 회원 존재함
when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.of(fixture));
// save() 어떤 파라메터로든 호출 시 사용자가 정의한 UserEntity return하도록 정의
when(userEntityRepository.save(Mockito.any())).thenReturn(Optional.of(fixture));
SnsApplicationException e = Assertions.assertThrows(SnsApplicationException.class, ()->userService.join(userName, password));
Assertions.assertEquals(ErrorCode.DUPLICATED_USER_NAME, e.getErrorCode());
}
// 로그인 성공
@Test
void 로그인_성공(){
String userName = "userName";
String password = "password";
UserEntity fixture = UserEntityFixture.get(userName, password);
// 회원가입 되어 있을 때
when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.of(fixture));
// 비밀번호가 일치할 때
when(encoder.matches(password, fixture.getPassword())).thenReturn(true);
Assertions.assertDoesNotThrow(()->userService.login(userName,password));
}
// 로그인 실패 존재하지 않는 회원
@Test
void 로그인_실패_존재하지_않는_회원(){
String userName = "userName";
String password = "password";
UserEntity fixture = UserEntityFixture.get(userName, password);
// 회원가입 되어 있을 때
when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.empty());
// // 비밀번호가 일치할 때, 아래 mock 주석해놓으면 라이브러리에서 정의 안 된 mock message는 false 리턴하는 것 확인하였음
// when(encoder.matches(password, fixture.getPassword())).thenReturn(true);
SnsApplicationException e = Assertions.assertThrows(SnsApplicationException.class, ()->userService.login(userName,password));
Assertions.assertEquals(HttpStatus.NOT_FOUND, e.getErrorCode().getStatus());
}
// 로그인 실패 비밀번호가 틀린 경우
@Test
void 로그인_실패_비밀번호가_틀린_경우(){
String userName = "userName";
String password = "password";
UserEntity fixture = UserEntityFixture.get(userName, password);
// 회원가입 되어 있을 때
when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.of(fixture));
// 비밀번호가 일치할 때
when(encoder.matches(password, fixture.getPassword())).thenReturn(false);
SnsApplicationException e = Assertions.assertThrows(SnsApplicationException.class, ()->userService.login(userName,password));
Assertions.assertEquals(HttpStatus.UNAUTHORIZED, e.getErrorCode().getStatus());
}
}
'테스트 > 테스트코드' 카테고리의 다른 글
Mockito 메소드 종류 (0) | 2024.03.09 |
---|---|
Mockito, @Mock, @MockBean 등 어노테이션 설명 잘 되어 있는 블로그 (0) | 2023.08.13 |
JUnit 5 기초 (Chapter 5) (0) | 2023.05.02 |
JUnit5 관련 어노테이션이나 설정관련 설명 정리 (0) | 2023.04.19 |
스프링부트 각 계층 테스트 하는 방법 (0) | 2023.01.03 |
댓글