본문 바로가기

Backend/Spring

Kotest를 통한 DCI 패턴 적용

프로젝트를 진행하면서 Controller 테스트를 작성하였고, 해당 코드에 대해 리뷰어로부터 다음과 같은 리뷰를 받게 되었다.

 

기존 테스트 코드는 다음과 같은 형태로 작성하였다.

@WebMvcTest(TestController::class)
class TestControllerTest : ControllerTestHelper() {
    @Test
    fun `테스트 API - 성공`() {
        ---
    }

    @Test
    fun `테스트 API - 실패 (name is empty)`() {
        ---
    }
}

왜 리뷰어께서 위와 같은 리뷰를 남기셨는지 의문이 들었고, 의문을 바탕으로 알아본 DCI 패턴에 대해 작성하고자 한다.

 

DCI 패턴이란?

DCI 패턴은 BDD 테스트 코드 작성 패턴으로, BDD 패턴은 코드의 행동을 설명하는 테스트 코드를 작성하는데 의의를 둔다.

반면, Describe - Context -It (DCI 패턴)은 Given - When -Then과 비슷하면서도 다른 점이 있다. 상황을 설명하기 보다 테스트 대상을 주인공 삼아 행동을 더 섬세하게 설명하는데 적합하다.

 

💬 DCI 핵심 키워드

Describe: 설명할 테스트 대상을 명시한다.

Context: 테스트 대상이 놓인 상황을 설명한다.

It: 테스트 대상의 행동을 설명한다.

 

👍 장점

◼ 테스트 코드를 계층 구조로 만들어준다.

◼ 테스트 코드를 추가하거나 읽을 때, 스코프 범위만 신경 쓰면 된다.

◼ 테스트 결과가 한 눈에 파악하기 좋게 트리 구조로 출력되어 가독성이 좋다.

 

 

DCI 패턴 적용하기

Kotest에서 DCI 패턴의 테스팅 스타일을 지원하기 때문에 Kotest를 사용하여 간편하게 DCI 패턴의 테스트 코드를 작성할 수 있다.

 

💬 Kotest?

코틀린을 위한 오픈 소스 테스트 프레임워크로, Kotlin DSL 을 활용한 다양한 테스팅 스타일을 지원하고 Junit과 호환이 된다.

 

describe("---") {
  context("---") {
    it("---") {
        ---
    }
  }
}

◼ 위와 같은 형태로 테스트 코드를 작성할 수 있다.

 

DCI 패턴을 적용한 Controller 단위 테스트

@WebMvcTest(TestController::class)
class TestControllerTest(---) : DescribeSpec({

    describe("POST /test") {
        val targetUri = "/test"
        context("유효한 요청 데이터가 전달되면") {
            val request = createTestRequest()
            it("trim을 적용하고 해당 값과 hashCode를 응답한다.") {
                mockMvc.post(targetUri) {
                    jsonContent(request)
                }.andExpect {
                    status { isOk() }
                }.andDo {
                    handle(
                        document(
                            "{class-name}/test-success",
                            requestFields(
                                fieldWithPath("name").description("이름").attributes(field(EXAMPLE, request.name))
                            ),
                            responseFields(
                                fieldWithPath("hashValue").description("name의 hashCode 값"),
                                fieldWithPath("originalName").description("trim을 적용한 name 값")
                            )
                        )
                    )
                }
            }
        }
})

 

결론

DCI 패턴을 적용해서 계층형으로 가독성 좋게 테스트 코드를 작성하는 것이 좋을 것 같다.

'Backend > Spring' 카테고리의 다른 글

kotlin + HttpInterface 알아보기  (0) 2023.06.22
Kotlin에서 Rest Docs 문서화 코드 개선하기  (0) 2023.05.29
spring에서 flyway 사용하기  (0) 2023.05.26
[Spring] checkstyle 적용하기  (0) 2023.05.03
DDD(Domain Driven Design)란?  (1) 2023.04.03