[Kotlin] JUnit5 & Mockito 정리

rockstar·2023년 6월 15일

Kotlin

목록 보기
1/2

  • ControllerTest
    @SpringBootTest와 @AutoConfigureMockMvc를 사용하자
  • RepositoryTest
    @DataJpaTest, @ExtendWith(SpringExtension::class), @Transaction을 사용하자.

@Transactional

해당 애노테이션은 JPA 테스트에서 사용할 때에만 동작한다. 따라서 @DataJpaTest를 사용하지 않는 경우에는 @Transactional가 동작하지 않는다. @DataJpaTest을 @Transactional과 함께 사용하는 것이 일반적이다.

@DataJpaTest

JPA 관련 빈들만 로드하여 슬라이스 테스트를 작성할 때 사용되고, @Entity가 붙은 엔티티 클래스와 @Repository이 붙은 레파지토리 인터페이스를 테스트하기에 적합하다. 내부적으로 스프링 애플리케이션 컨텍스트를 로드하며, JUnit5를 사용할 경우 @ExtendWith(SpringExtension::class)를 함께 사용한다. 인메모리 구조의 데이터베이스를 사용해서 Entity와 JpaRepository를 가지고 테스트할 수 있게 도와주며, 물론 설정을 통해 디스크 방식의 데이터베이스를 사용할 수 있다. 아래의 예시 코드에서 보겠지만 @AutoConfigureTestDatabase(replace=AutoConfigureTestDatabase.Replace.NONE)를 사용하면 된다.

@SpringBootTest

전체 스프링 애플리케이션 컨텍스트를 로드하여 통합 테스트를 작성할 때 사용된다. 애플리케이션에서 사용되는 모든 빈들을 로드합니다. 내부적으로 스프링 애플리케이션 컨텍스트를 로드하며, JUnit5를 사용할 경우 @ExtendWith(SpringExtension::class)를 함께 사용한다.

@ExtendWith(SpringExtension::class)

JUnit5에서 스프링과 관련된 테스트 기능들을 사용할 수 있도록 확장(extension)해주는 클래스이며, JUnit5를 사용하는 테스트 클래스에서는 @ExtendWith(SpringExtension::class)를 선언해주어야 스프링의 테스트 확장 기능을 활성화할 수 있다. @SpringBootTest, @DataJpaTest등과 함께 사용된다.

@AutoConfigureMockMvc

@AutoConfigureMockMvc는 MockMvc 객체를 자동으로 구성하여 컨트롤러를 테스트하기 위한 애노테이션이고, 이 애노테이션을 사용하면 MockMvc 객체를 주입받을 수 있으며, 컨트롤러의 HTTP 요청을 테스트할 수 있다.

ControllerTest

@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()
        }
    }
}

잘못된 정보는 지적해주시면 감사하겠습니다.

0개의 댓글