[Spring Boot] Kotest + Mockk

Spring Boot

Language :

Kotest

kotlin 코드를 테스트하고 검증할 수 있는 오픈 소스 테스트 프레임워크

다양한 상황을 테스트할 수 있도록 10가지 테스트 레이아웃을 제공한다. (링크)

Mockk

Kotlin Mocking 프레임워크

DSL(Domain Specific Language) 기반으로 테스트 코드를 작성한다.

  • Mocking: 모의 객체. 외부 서비스나 모듈을 가상으로 대체하는 테스트용 객체

예제

BDD(Behavior Driven Development) 방식인 BehaviorSpec를 사용하여 Service 테스트

build.gradle.kts

kotlin

testImplementation("io.kotest:kotest-runner-junit5:5.5.5")
testImplementation("io.kotest:kotest-assertions-core:5.5.5")
testImplementation("io.mockk:mockk:1.13.4")

Intellij Plugin Install

  • Settings → Plugins → ‘Kotest’ 검색 → 설치

intellij_kotest.png

service (src>main>kotlin>package-path>service>UserServiceImpl)

kotlin

@Service
class UserServiceImpl(
    private val userRepository: UserRepository
) : UserService {

    override fun login(email: String, password: String): String {
        // 계정 조회
        val user = userRepository.findByEmail(email) ?: throw RuntimeException("email? $email")
        // 비밀번호 확인
        if (user.password != password) throw PasswordFailException()
        return getSession(email)
    }

    override fun getSession(email: String): String {
        return "session-key"
    }

}

test (src>test>kotlin>package-path>service>UserServiceTest)

kotlin

internal class UserServiceTest : BehaviorSpec({
    // UserService 의존성 객체 선언
    val userRepository = mockk<UserRepository>()
    // 테스트 데이터 선언
    var email: String
    var password: String

    Given("로그인 테스트") {
        email = "test@gmail.com"
        password = "test-password"

        // UserService에 의존성 객체 주입
        val service = withContext(Dispatchers.IO) {
            UserServiceImpl(userRepository)
        }

        When("올바른 계정을 입력하면") {
            // 계정 조회 결과값을 임의로 설정
            every { userRepository.findByEmail(any()) } returns user
            Then("로그인 성공") {
                val result = service.login(email = email, password = password)
                // 결과값 검증
                result shouldNotBe null
                result shouldBe "session-key"
            }
        }

        When("올바르지 않은 계정을 입력하면") {
            And("존재하지 않는 이메일을 입력하면") {
                every { userRepository.findByEmail(any()) } returns null

                Then("예외가 발생한다") {
                    val result = shouldThrow<RuntimeException> {
                        service.login(email = email, password = password)
                    }
                    result.message shouldBe "email? $email"
                }
            }
            And("비밀번호를 틀리게 입력하면") {
                password = "test-password-1"
                every { userRepository.findByEmail(any()) } returns user

                Then("예외가 발생한다") {
                    shouldThrow<PasswordFailException> {
                        service.login(email = email, password = password)
                    }
                }
            }
        }
    }
}) {
    companion object {
        val user = User(
            id = 1L,
            email = "test@gmail.com",
            password = "test-password"
        )
    }
}

테스트 실행

Kotest Plugin으로 좌측에 표시되는 녹색 화살표를 누르면 각 단계별로 테스트를 실행할 수 있다.

Given부터 정상 실행되면 다음과 같은 결과가 나온다.

intellij_kotest_given.png

전체 코드 링크

민갤

Back-End Developer

백엔드 개발자입니다.