[TIL/Kotlin] Junit5로 테스트 코드 작성하기

2023. 12. 12. 20:39·TIL/Kotlin
728x90
반응형

1. Junit5에서 사용되는 5가지 어노테이션

1) @Test : 테스트 메소드를 지정한다. 테스트 메소드를 싱행하는 과정에서 오류가 없으면 성공

2) @BeforeEach : 각 테스트 메소드가 수행되기 전에 실행되는 메소드를 지정. 매번 실행

3) @AfterEach : 각 테스트 메소드가 수행된 후에 실행되는 메소드를 지정. 매번 실행

4) @BeforeAll : 모든 테스트를 수행하기 전에 최초 1회 수행되는 메소드를 지정

5) @AfterAll : 모든 테스트를 수행한 후 최후 1회 수행되는 메소드를 지정

 

* BeforeAll과 AfterAll은 @JvmStatic을 붙여줘야한다.

package com.group.libraryapp

import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class JunitTest {

    companion object {
        @BeforeAll
        @JvmStatic
        fun beforeAll() {
            println("모든 테스트 시작 전")
        }

        @AfterAll
        @JvmStatic
        fun afterAll() {
            println("모든 테스트 종료 후")
        }
    }
    
    @BeforeEach
    fun beforeEach() {
        println("각 테스트 시작 전")
    }

    @AfterEach
    fun afterEach() {
        println("각 테스트 종료 후")
    }

    @Test
    fun test1() {
        println("테스트 1")
    }

    @Test
    fun test2() {
        println("테스트 2")
    }
}

 

실행 결과


2. 단언문

  • assertThat(확인하고 싶은 값)
  • .isEqualTo(기대하는 값)
  • .isTrue / .isFalse 주어진 값이 true인지 false인지 검증
  • .hasSize(기대하는 사이즈)
  • .extracting(name).containsExactlyInAnyOrder("A","B") : 해당하는 리스트들의 name만 가져와서 그 값이 정확히 A인지 B인지 검증. 순서는 검증하지 않기 때문에 순서는 중요하지 않음
  • .containsExactly("A", "B") : 순서까지 검증
  • assertThrows<IllegalArgumentException> { 
        function1() 
    } : function1 함수를 실행했을 때 IllegalArgumentException이 나오는지 검증
  • val message = assertThrows<IllegalArgumentException> { 
        function1() 
    }.message
    assertThat(message).isEqualTo("잘못된 값이 들어왔습니다") : message를 가져와 예외 메시지를 확인할 수 있음

3. Spring Boot 각 계층을 테스트 하는 방법

- Domain 계층 : 클래스를 테스트 하는 것과 동일

- Service, Repository 계층 : 스프링 빈을 사용하는 테스트 방법 사용 (@SpringBootTest), 데이터 위주의 검증

- Controller 계층 : 스프링 빈을 사용하는 테스트 방법 사용 (@SpringBootTest), 응답 받은 JSON을 비롯한 HTTP 위주의 검증

 

딱 1개의 계층만 테스트 한다면 보통은 Service 계층을 테스트

A를 보냈을 때 B가 잘 나오는지, 원하는 로직을 잘 수행하는지 검증 가능


4. 테스트 코드 작성

package com.group.libraryapp.service.user

import com.group.libraryapp.domain.user.User
import com.group.libraryapp.domain.user.UserRepository
import com.group.libraryapp.dto.user.request.UserCreateRequest
import com.group.libraryapp.dto.user.request.UserUpdateRequest
import org.assertj.core.api.AssertionsForInterfaceTypes.assertThat
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
// @Autowired constructor를 붙이면 각각 @Autowired를 붙이지 않아도 됨
class UserServiceTest @Autowired constructor(
    private val userRepository: UserRepository,
    private val userService: UserService,
) {

    // DB를 공유자원으로 사용하고 있기 때문에 각 테스트 코드를 실행한 뒤에 자원을 비우도록 하기 위함
    @AfterEach
    fun clean() {
        userRepository.deleteAll()
    }

    @Test
    @DisplayName("유저 저장이 정상 동작한다.")
    fun saveUserTest() {
        // given
        val request = UserCreateRequest("아무개", null)

        // when
        userService.saveUser(request)

        // then
        val results = userRepository.findAll()
        assertThat(results).hasSize(1)
        assertThat(results[0].name).isEqualTo("아무개")
        assertThat(results[0].age).isNull() // Java와 Kotlin의 자료형 차이 때문에 Exception 발생하는데 User에서 어노테이션을 붙여줘야함
    }

    @Test
    @DisplayName("유저 조회가 정상 동작한다.")
    fun getUsersTest() {
        // given
        userRepository.saveAll(listOf(
            User("A", 20),
            User("B", null)
        ))

        // when
        val results = userService.getUsers()

        // then
        assertThat(results).hasSize(2)
        assertThat(results).extracting("name").containsExactlyInAnyOrder("A", "B")
        assertThat(results).extracting("age").containsExactlyInAnyOrder(20, null)
    }

    @Test
    @DisplayName("유저 업데이트가 정상 동작한다.")
    fun updateUserNameTest() {
        // given
        val savedUser = userRepository.save(User("A", null))
        val request = UserUpdateRequest(savedUser.id, "B")

        // when
        userService.updateUserName(request)

        // then
        val result = userRepository.findAll()[0]
        assertThat(result.name).isEqualTo("B")
    }

    @Test
    @DisplayName("유저 삭제가 정상 동작한다.")
    fun deleteUserTest() {
        // given
        userRepository.save(User("A", null))

        // when
        userService.deleteUser("A")

        // then
        assertThat(userRepository.findAll()).isEmpty()
    }


}

번외)

전체 테스트 코드를 실행하려면

인텔리제이에서 터미널에 ./gradlew test 명령어로 실행을 시키거나

우측에 있는 gradle 클릭 후 Tasks > verification > test 실행을 시키면 테스트 코드 전체를 실행시킬 수 있다.

728x90
반응형

'TIL > Kotlin' 카테고리의 다른 글

[TIL/Kotlin] Kotlin과 JPA를 사용할 때 이야기거리 3가지  (0) 2023.12.23
[TIL/Kotlin] Kotlin, SpringBoot, JPA nativeQuery 사용시 주의사항  (0) 2023.12.05
[TIL/Kotlin] 우체국 Open API로 EMS 배송 추적하기  (0) 2023.10.15
[TIL/Kotlin] 코틀린 고급문법_sealed 클래스, 위임된 프로퍼티, 클래스 위임  (0) 2023.05.27
[TIL/Kotlin] 코틀린 고급문법_열거 클래스(Enum Class)와 열거 클래스에 프로퍼티와 멤버 함수 선언 및 활용하기  (0) 2023.05.27
'TIL/Kotlin' 카테고리의 다른 글
  • [TIL/Kotlin] Kotlin과 JPA를 사용할 때 이야기거리 3가지
  • [TIL/Kotlin] Kotlin, SpringBoot, JPA nativeQuery 사용시 주의사항
  • [TIL/Kotlin] 우체국 Open API로 EMS 배송 추적하기
  • [TIL/Kotlin] 코틀린 고급문법_sealed 클래스, 위임된 프로퍼티, 클래스 위임
야리니
야리니
오늘보다 내일 더 성장하는 개발자가 되기 위한 야리니 블로그입니다 :)
    반응형
    250x250
  • 야리니
    야리니의 step by step
    야리니
  • 링크

    • GitHub
    • Linkedin
  • 전체
    오늘
    어제
    • 분류 전체보기 (477)
      • TIL (379)
        • Java (97)
        • Kotlin (28)
        • JPA (16)
        • Spring (37)
        • Oracle (22)
        • JDBC (7)
        • Web(HTML, CSS, JS, jQuery) (90)
        • View Template (31)
        • AWS (7)
        • HTTP (7)
        • CS (5)
        • Linux, Unix (2)
        • Python (20)
      • Trouble Shooting(Error) (37)
      • Algorithm (15)
      • Git,GitHub (8)
      • Diary (23)
      • 독서 (9)
      • Etc (6)
        • Mac (1)
        • 학원준비과정 (2)
  • 블로그 메뉴

    • 방명록
    • 태그
  • 공지사항

    • 안녕하세요 :)
  • 인기 글

  • 태그

    java기초
    국비지원학원
    java
    코틀린
    CSS
    Kotlin
    쌍용교육센터
    백엔드 개발자
    HTML
    oracle
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
야리니
[TIL/Kotlin] Junit5로 테스트 코드 작성하기
상단으로

티스토리툴바