SpringBoot 테스트의 종류
Domain 계층 - 클래스 테스트하는 것과 동일
Repository, Service 계층 - @SpringBootTest 를 이용. 스프링 빈을 사용하는 테스트. 데이터 위주의 검증.
Controller 계층 - @SpringBootTest 를 이용. 스프링 빈을 사용하는 테스트. 응답받은 JSON을 비롯한 HTTP 위주의 검증.
모든 계층을 테스트하는 것이 좋지만, 현실적으로 딱 한개의 계층만 테스트해야한다면
보통은 Service 계층을 테스트한다.
-> 그래도 Controller는 별도로 추가적인 테스트가 필요하다. 테스트 방식이 조금 다르기 때문.
테스트할 클래스에 커서를 두고 Cmd + Enter를 누르면 Test 생성을 간편하게 할 수 있다.
코틀린 테스트코드 예시
@SpringBootTest
class UserServiceTest @Autowired constructor(
private val userRepository: UserRepository,
private val userService: UserService
) {
@Test
@DisplayName("유저 저장이 정상 동작한다") // 한글로 네이밍
fun saveUserTest() {
// given
val request = UserCreateRequest("hevton", 20)
// when
userService.saveUser(request)
// then
val results = userRepository.findAll()
assertThat(results).hasSize(1)
assertThat(results[0].name).isEqualTo("hevton")
assertThat(results[0].age).isEqualTo(20)
}
}
테스트는 given - when - then 패턴을 사용한다.
assertThat이 import가 안된다면, 다음 문장을 수작업으로 입력해준다.
import org.assertj.core.api.Assertions.*
테스트에는 지금과 같은 assertThat과 assertThrows가 주로 쓰인다.
assertThrows는, 코드 중 예외를 발생시키는 부분이 진짜 예외를 잘 발생시키고 있는지를 테스트하는 것이다.
assertThrows<IllegalArgumentException> {
bookService.loanBook(request)
}.apply {
assertThat(this.message).isEqualTo("대출중")
}
loanBook함수는 책 대출을 요청하는데, 해당 책이 이미 대출중이라면 Exception을 발생시키도록 설계되어있다.
따라서 테스트코드에서, 이미 대출중인 책에 대해 request를 요청했을 때 진짜로 "대출중" 이라는 Exception이 발생하는지 테스트하는것이다.
1. 추가로 Cmd + N을 이용하면 단축키 기능을 조금 더 사용할 수 있다.
2. 또한, 프로젝트의 전체 테스트를 다 진행하고 싶다면 터미널에서 아래와 같이 입력하면 된다.
./gradlew test
또는 이렇게 IDE를 이용해서도 할 수 있다.
첫번째 방법보다 어디서 틀렸는지 추적이 쉽다.
근데 실행하여 빌드하면 기본적으로 테스트가 전제되어서 사실 크게 관심가지지 않아도 된다.