목차
TL;DR;
Kotlin
테스트의 Assertion을 쉽게 도와주는 Kluent
를 소개합니다.
UnitTest(Mock Test)
와 Integration Test
를 기준으로 나누어 설명합니다.
Common하게 쓰이는 Service Layer
의 UnitTest
를 실제 Github Repo 예제를 통해 학습합니다.
Kluent
Kluent
는 Kotlin을 위해 특별히 작성된 "Fluent Assertions"
라이브러리입니다.
Kotlin 의 Infix-Notations 및 Extension Functions 를 사용하여 JUnit-Assertions에 대한 유창한 래퍼를 제공합니다.
Example
Integration Test
IT Test는 WebTestClient
를 이용합니다.
Config
WebTestClient
를 설정합니다.
Example
다음과 같이 api를 직접 호출하여 결과값을 Assertion하며 테스트를 진행할 수 있습니다.
ConsmeWith
를 통해 Kluent
로 Body값을 Assertion하여 테스트를 진행할 수 있습니다.
UnitTest (Mock Test)
Mockking은 왜할까?
- mockking에 대한 여러 사용처가 있지만, 여기서는
Service Layer
테스트하는 것을 주로 설명합니다. - 테스트 할 시, 통합적인 환경을 테스트하고 싶은 것이 아닌, 특정 부분만 테스트 하고 싶을 경우가 있습니다.
- 보통
Service Layer
가 그에 해당하며, 해당 부분을 제외한 것을 mockking 하여 Service만 테스트하기 위해 사용합니다. - 다른 모든 부분을 mockking 하였으니 테스트 자체도 매우 가볍고, CI 또한 구성하기 매우 쉽습니다.
- 아래에서는 사용 방법을 설명합니다.
Mock DSL Basic
- 기본적인 사용법입니다.
- corutine(suspending) 함수의 경우 co를 prefix로 붙여진 함수를 사용합니다.
Mock 객체 주입
아래와 같이 mock
객체를 생성합니다.
- junit5를 기준으로 설명합니다.
- mockiing 후 추가적으로 객체의 행위를 정의해줘야 합니다.
아래 처럼 relaxed mock
을 사용할 수 있습니다.
- relaxed mock는 모든 함수에 대해 간단한 값을 반환하는 모의 객체입니다.
- 이를 통해 각 경우에 대한 동작 지정을 건너 뛰고 필요한 것을 스텁 할 수 있습니다.
아래 처럼 mocking을 해제할 수 있습니다.
Mock 행위 정의
함수 리턴 값 정의
- returns는 컴파일되는 시점의 값을 단 한번만 인식하여 그대로 행하게 됩니다.
함수 행위 정의
- justRun 또한 컴파일되는 시점의 값을 단 한번만 인식하여 그대로 행하게 됩니다.
함수 전체 정의
- answers를 이용하면 런타임 시 해당 함수를 호출하게 합니다.
Varargs
- 확장 된 variable 처리가 가능합니다.
Hierarchical Mocking
- 객체 mocking 후 바로 행위를 정의할 수 있습니다.
Mock Assertion
함수 호출 카운트 확인
- atLeast, atMost또는 exactly매개 변수를 사용하여 호출 수를 확인할 수 있습니다 .
함수 호출 순서 확인
verifySequence
: 호출이 지정된 순서로 발생했는지 확인합니다.
시간 초과 확인
- 동시 작업을 확인하려면 다음을 사용할 수 있습니다
timeout = xxx
Common Example
Repository Mocking
Apply Mocking UnitTest by wnsgml972 · Pull Request #55 · Coffee-Street/strada
- 데이터 소스를 Mocking 합니다.
- 데이터베이스의 행위를 인메모리 상에서 동작할 수 있게
MutableMap
을 이용해 행위를 정의합니다. - Mocking된 함수의 호출 카운트를 검증하여 Service Logic이 정확하게 동작하는 것을 검증합니다.