PHM 2023. 7. 31. 16:00

1. 도서관리 애플리케이션 이해하기

2. 테스트 코드란 무엇인가, 그리고 왜 필요한가?!

테스트 코드는 왜 필요한가?!

- 1. 개발 과정에서 문제를 미리 발견할 수 있다.

- 2. 기능 추가와 리팩토링을 안심하고 할 수 있다.

- 3. 빠른 시간 내 코드의 동작 방식과 결과를 확인할 수 있다.

- 4. 좋은 테스트 코드를 작성하려 하다보면, 자연스럽게 좋은 코드가 만들어 진다.

- 5. 잘 작성한 테스트는 문서 역할을 한다. (코드리뷰를 돕는다.)

 

3. 코틀린 코드 작성 준비하기

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.6.21'
}

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
}

compileKotlin {
    kotlinOptions {
        jvmTarget = "11"
    }
}

compileTestKotlin {
    kotlinOptions {
        jvmTarget = "11"
    }
}

 

4. 사칙연산 계산기에 대해 테스트 코드 작성하기

테스트 코드의 3부분 ( given - when - then 패턴 )

- 1. 테스트 대상을 만들어 준비하는 과정

- 2. 실제 우리가 테스트하고 싶은 기능을 호출하는 과정

- 3. 호출 이후 의도한대로 결과가 나왔는지 확인하는 과정

 

5. 사칙연산 계산기의 나눗셈 테스트 작성

6. Junit5 사용법과 테스트 코드 리팩토링

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

@Test - 테스트 메소드를 지정한다.
- 테스트 메소드를 실행하는 과정에서 오류가 없으면 성공한다.
@BeforeEach - 각 테스트 메소드가 수행되기 전에 실행되는 메소드를 지정한다.
@AfterEach - 각 테스트가 수행된 후에 실행되는 메소드를 지정한다.
@BeforeAll - 모든 테스트 수행하기 전에 최초 1회 수행되는 메소드를 지정한다.
@AfterAll - 모든 테스트를 수행한 후 최후 1회 수행되는 메소드를 지정한다.

- BeforeAll, AfterAll 에는 @JvmStatic 을 붙여줘야 한다.

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")
    }
}

 

단언문

- assertThat(확인하고 싶은 값)

- .isEqualTo(기대값)

- .isTrue / .isFalse : 주어진 값이 true 인지 / false 인지 검증

- .hasSize(기대값) : 주어진 컬렉션의 size가 원하는 값인지 검증

 

val people = listOf(Person("A"), Person("B"))
assertThat(people).extracting("name").containsExactlyInAnyOrder("A","B")

- 주어진 컬렉션 안의 item 들에서 name 이라는 프로퍼티를 추출한 후, 그 값이 A와 B인지 검증 (이 때 순서는 중요하지 않다)

- .coinsExactly : 순서까지 체크

 

assertThrow<IllegalArgumentException> {
    function1()
}

- function1 함수를 실행했을 때 IllegalArgumentException 이 나오는지 검증

 

val message = assertThrows<IllegalArgumentException> {
    function1()
}.message
assertThat(message).isEqualTo("잘못된 값이 들어왔습니다")

- message 를 가져와 예외 메시지를 확인할 수도 있다.

 

7. Junit5으로 Spring Boot 테스트하기

Spring Boot 의 Layered Architecture

- 스프링 컨텍스트에 의해 관리되는 Bean

    ㆍController - Service - Repository

- 순수한 Java 객체(POJO)

    ㆍDomain

 

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

- Domain 계층

    ㆍ클래스를 테스트하는 것과 동일

- Service, Repository 계층

    ㆍ스프링 빈을 사용하는 테스트 방법 사용 (@SpringBootTest)

    ㆍ데이터 검증 위주

- Controller 계층

    ㆍ스프링 빈을 사용하는 테스트 방법 사용 (@SpringBootTest)

    ㆍ응답 받은 JSON을 비롯한 HTTP 위주의 검증

 

어떤 계층을 테스트 해야 할까?!

- 당연히 BEST는 모든 계층에 대해 많은 case를 검증하는 것!

- 하지만 현실적으로 코딩 시간을 고려해 딱 1개 계층만 테스트 한다면...

    ㆍ개인적으로 (보통은) Service 계층을 테스트 합니다!

    ㆍA를 보냈을 때 B가 잘나오는지, 원하는 로직을 잘 수행하는지 검증할 수 있기 때문

 

8. 유저 관련 기능 테스트 작성하기

9. 책 관련 기능 테스트 작성하기

10. 테스트 작성 끝! 다음으로!

- 작성한 모든 테스트를 돌리고 싶을 때

    ㆍ(터미널) ./gradlew test

    ㆍGradle - Tasks - verification - test

 

정리

1. Kotlin을 사용하기 위해 필요한 설정 방법

2. 테스트란 무엇이고, 왜 중요한가

3. Junit5의 기초 사용법

4. Junit5와 Spring Boot를 함께 사용해 테스트를 작성하는 방법

5. 여러 API에 대한 Service 계층 테스트 실습