
- ControllerTest
@SpringBootTest와 @AutoConfigureMockMvc를 사용하자- RepositoryTest
@DataJpaTest, @ExtendWith(SpringExtension::class), @Transaction을 사용하자.
해당 애노테이션은 JPA 테스트에서 사용할 때에만 동작한다. 따라서 @DataJpaTest를 사용하지 않는 경우에는 @Transactional가 동작하지 않는다. @DataJpaTest을 @Transactional과 함께 사용하는 것이 일반적이다.
JPA 관련 빈들만 로드하여 슬라이스 테스트를 작성할 때 사용되고, @Entity가 붙은 엔티티 클래스와 @Repository이 붙은 레파지토리 인터페이스를 테스트하기에 적합하다. 내부적으로 스프링 애플리케이션 컨텍스트를 로드하며, JUnit5를 사용할 경우 @ExtendWith(SpringExtension::class)를 함께 사용한다. 인메모리 구조의 데이터베이스를 사용해서 Entity와 JpaRepository를 가지고 테스트할 수 있게 도와주며, 물론 설정을 통해 디스크 방식의 데이터베이스를 사용할 수 있다. 아래의 예시 코드에서 보겠지만 @AutoConfigureTestDatabase(replace=AutoConfigureTestDatabase.Replace.NONE)를 사용하면 된다.
전체 스프링 애플리케이션 컨텍스트를 로드하여 통합 테스트를 작성할 때 사용된다. 애플리케이션에서 사용되는 모든 빈들을 로드합니다. 내부적으로 스프링 애플리케이션 컨텍스트를 로드하며, JUnit5를 사용할 경우 @ExtendWith(SpringExtension::class)를 함께 사용한다.
JUnit5에서 스프링과 관련된 테스트 기능들을 사용할 수 있도록 확장(extension)해주는 클래스이며, JUnit5를 사용하는 테스트 클래스에서는 @ExtendWith(SpringExtension::class)를 선언해주어야 스프링의 테스트 확장 기능을 활성화할 수 있다. @SpringBootTest, @DataJpaTest등과 함께 사용된다.
@AutoConfigureMockMvc는 MockMvc 객체를 자동으로 구성하여 컨트롤러를 테스트하기 위한 애노테이션이고, 이 애노테이션을 사용하면 MockMvc 객체를 주입받을 수 있으며, 컨트롤러의 HTTP 요청을 테스트할 수 있다.
@Transactional
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest{
@Autowired lateinit var mockMvc: MockMvc
@Test
fun createUser(){
var json = """
{
"username": "dlwodud821",
"password": "1234"
}
""".trimIndent()
mockMvc.perform(post("/user")
.content(json)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.username").value("dlwodud821"))
.andExpect(jsonPath("$.password").value("1234"))
}
@Test
fun getUser(){
mockMvc.perform(get("/user/2"))
.andExpect(status().isOk)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.username").value("dlwodud821"))
.andExpect(jsonPath("$.password").value("1234"))
}
}
RepositoryTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ExtendWith(SpringExtension::class)
@Transactional
@DataJpaTest
class UserRepositoryTest(
@Autowired var userRepository: UserRepository
) {
lateinit var userEntity: User
lateinit var savedUser: User
@BeforeEach
fun init(){
userEntity = User(username = "dlwodud821", password = "1234")
savedUser = userRepository.save(userEntity)
}
@Test
@DisplayName("유저 생성")
fun saveUser() {
var findUser: User? = userRepository.findByUsername(userEntity.username)
assertThat("dlwodud821").isEqualTo(findUser?.username)
assertThat("1234").isEqualTo(findUser?.password)
}
@Test
@DisplayName("유저 삭제")
fun deleteUser() {
userRepository.delete(savedUser)
var findUser: Optional<User>
savedUser.id?.let {
findUser = userRepository.findById(it)
assertThat(findUser).isEmpty()
}
}
}
잘못된 정보는 지적해주시면 감사하겠습니다.