단위 테스트는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트
이다. 여기서 모듈은 어플리케이션에서 작동하는 하나의 기능 또는 메소드이다.
즉, 단위 테스트는 어플리케이션으 구성하는 하나의 기능이 올바르게 동작하는지를 독립적으로 테스트하는 것이다. "어떤 기능이 실행되면 어떤 결과가 나온다" 정도를 테스트를 통해 검증한다.
통합 테스트는 모듈을 통합하는 과정에서 모듈 간의 호환성을 확인하기 위해 수행되는 테스트
이다. 일반적으로 어플리케이션은 여러 개의 모듈로 구성되어 있고, 모듈들이 메시지를 주고 받으면서 기능을 수행한다.
그렇기에 통합된 모듈들이 올바르게 연계되어 동작하는지 검증이 필요한데, 이러한 목적으로 진행되는 테스트가 통합 테스트이다.
스프링에서는 @Mock
(모의 객체) 을 사용하여 다른 레이어와 분리된 단위 테스트를 진행할 수 있다.
유저 테스트 예시
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
UserRepository userRepository;
@Mock
PasswordEncoder passwordEncoder;
@Mock
JwtUtil jwtUtil;
@InjectMocks
UserService userService;
@Test
@DisplayName("회원가입 성공")
void 회원가입성공() {
//given
UserRequestDTO userRequestDTO = createUserRequestDTO();
when(userRepository.findByUserId(anyString())).thenReturn(Optional.empty());
when(userRepository.findByEmail(anyString())).thenReturn(Optional.empty());
when(passwordEncoder.encode(anyString())).thenReturn("encodedPassword");
User user = User.builder()
.userId(userRequestDTO.getUserId())
.password("encodedPassword")
.name(userRequestDTO.getName())
.email(userRequestDTO.getEmail())
.userType(UserType.UNVERIFIED)
.introduce(userRequestDTO.getIntroduce())
.build();
when(userRepository.save(Mockito.any(User.class))).thenReturn(user);
//when
UserResponseDTO responseDTO = userService.createUser(userRequestDTO);
//then
assertThat(responseDTO).isNotNull();
assertThat(responseDTO.getUserId()).isEqualTo(userRequestDTO.getUserId());
assertThat(responseDTO.getName()).isEqualTo(userRequestDTO.getName());
assertThat(responseDTO.getEmail()).isEqualTo(userRequestDTO.getEmail());
assertThat(responseDTO.getIntroduce()).isEqualTo(userRequestDTO.getIntroduce());
}
@Test
@DisplayName("회원가입 실패 - 이미 존재하는 아이디")
void 회원가입실패_존재하는아이디() {
//given
UserRequestDTO userRequestDTO = createUserRequestDTO();
when(userRepository.findByUserId(anyString())).thenReturn(Optional.of(User.builder().build()));
//when - then
assertThatThrownBy(() -> userService.createUser(userRequestDTO))
.isInstanceOf(UserException.class)
.hasMessageContaining("중복된 id 입니다.");
}
@Test
@DisplayName("회원가입 실패 - 이미 존재하는 이메일")
void 회원가입실패_존재하는이메일() {
//given
UserRequestDTO userRequestDTO = createUserRequestDTO();
when(userRepository.findByUserId(anyString())).thenReturn(Optional.empty());
when(userRepository.findByEmail(anyString())).thenReturn(Optional.of(User.builder().build()));
//when - then
assertThatThrownBy(() -> userService.createUser(userRequestDTO))
.isInstanceOf(UserException.class)
.hasMessageContaining("중복된 Email 입니다.");
}
스프링에서는@SpringBootTest
어노테이션을 통해 직접 스프링 콘테이너를 띄우고 Bean을 주입 받아서 테스트를 진행할 수 있다
유저 테스트 예시
@SpringBootTest
@Transactional
@ActiveProfiles("test")
class UserServiceTest {
@Autowired
UserService userService;
@Autowired
private UserRepository userRepository;
@Test
@DisplayName("유저 생성 성공 테스트")
void 유저생성성공() {
//given
UserRequestDTO requestDTO = new UserRequestDTO();
requestDTO.setUserId("heesue");
requestDTO.setName("test");
requestDTO.setPassword("test");
requestDTO.setEmail("12123@gmail.com");
requestDTO.setIntroduce("test");
//when
UserResponseDTO responseDTO = userService.createUser(requestDTO);
//then
assertThat(responseDTO.getUserId()).isEqualTo(requestDTO.getUserId());
assertThat(responseDTO.getName()).isEqualTo(requestDTO.getName());
assertThat(responseDTO.getEmail()).isEqualTo(requestDTO.getEmail());
assertThat(responseDTO.getIntroduce()).isEqualTo(requestDTO.getIntroduce());
}
@Test
@DisplayName("유저 생성 실패 테스트 - 중복된 아이디")
void 유저생성실패_중복된아이디() {
//given
UserRequestDTO requestDTO = MonkeyUtils.commonMonkey().giveMeOne(UserRequestDTO.class);
requestDTO.setUserId("test");
//when
assertThatThrownBy(() -> userService.createUser(requestDTO))
.isInstanceOf(UserException.class);
}
@Test
@DisplayName("유저 생성 실패 테스트 - 중복된 이메일")
void 유저생성실패_중복된이메일() {
//given
UserRequestDTO requestDTO = MonkeyUtils.commonMonkey().giveMeOne(UserRequestDTO.class);
requestDTO.setEmail("test@gmail.com");
//when - then
assertThatThrownBy(() -> userService.createUser(requestDTO))
.isInstanceOf(UserException.class);
}