[kotlog] 코프링으로 블로그 만들기 - 5 (kotest)

dustle·2025년 6월 15일
1

kotlog

목록 보기
5/6

이번에는 Kotest 를 적용하고 간단한 Repository 테스트를 작성해보았습니다.

1. UserRepository 생성

먼저 테스트를 위해 User 패키지 내에 UserRepository 인터페이스를 생성하였습니다.
Spring Data JPA 의 JpaRepository 를 상속받아 기본적인 CRUD 기능을 제공합니다.

interface UserRepository : JpaRepository<User, Long>

2. Kotest 적용

원래 Java 에서는 @DisplayName@Nested 등을 활용해 한글 테스트 이름을 작성하고 given, when, then 구조는 주석으로 표현하는 방식이 일반적이었습니다.
반면 Kotest 는 주석 없이도 문법 자체로 표현할 수 있도록 설계되어 있어 테스트의 의도와 시나리오가 더 명확하게 드러납니다.
또한 Kotlin 에 친화적인 테스트 DSL 을 지원하기 때문에 이번 기회에 Kotest 를 도입해보게 되었습니다.

Kotest 의존성 추가

Spring + Gradle + Kotlin 기준으로 다음과 같이 설정하였습니다:

val kotestVersion = "5.9.1"

dependencies {
    testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion")
    testImplementation("io.kotest:kotest-assertions-core:$kotestVersion")
    testImplementation("io.kotest.extensions:kotest-extensions-spring:1.3.0")
}

tasks.withType<Test>().configureEach {
    useJUnitPlatform()
}

Spring Extension 적용 이유

처음에는 공식문서의 Quick Start 탭을 참고해 의존성을 추가했는데 테스트 실행 시 아래와 같은 예외가 발생했습니다:

SpecInstantiationException: Could not create instance of class ... Specs must have a public zero-arg constructor.

알고 보니 @SpringBootTest 환경에서 Kotest 를 사용할 경우 kotest-extensions-spring 모듈이 필요하며 이를 통해 Spring 의 의존성 주입 기능을 Kotest 내부에서도 사용할 수 있게 됩니다.

kotest-extensions-spring 은 다음과 같은 기능을 제공합니다:

  • Spring 확장 활성화
  • 생성자 주입(Primary constructor injection) 지원
  • @ContextConfiguration 및 Spring TestContext 사용
  • 테스트 메서드 전/후 콜백 기능

IntelliJ Kotest 플러그인 추가

각 테스트 옆에 실행 버튼(▶) 을 표시해주는 플러그인을 설치하였습니다.

3. FunSpec 을 이용한 Repository 테스트 작성

Kotest 는 여러 가지 스타일의 테스트 문법을 제공합니다:

  • FunSpec
  • BehaviorSpec
  • DescribeSpec
  • StringSpec
  • WordSpec
  • ShouldSpec

이 중에서 저는 대중적으로 사용되는 FunSpec 을 사용하였습니다.

@SpringBootTest
class UserRepositoryTest(
    val userRepository: UserRepository,
) : FunSpec({

    context("User 저장") {
        test("저장 성공") {
            val user = User(
                username = "dustle",
                password = "111",
                email = "111",
                nickname = "111"
            ).also {
                userRepository.save(it)
            }

            val result = userRepository.findById(user.id).get()

            result.also {
                it.username shouldBe user.username
                it.password shouldBe user.password
                it.email shouldBe user.email
                it.nickname shouldBe user.nickname
                it.id shouldNotBe null
                it.createdAt shouldNotBe null
                it.updatedAt shouldNotBe null
            }
        }
    }
})

이렇게 Kotest 를 적용해보았는데 공식 문서를 참고하면서 진행하다 보니 Spring 환경에서는 별도로 Extension을 추가해야 한다는 점을 놓쳐서 설정에 시간이 더 걸렸던 것 같습니다.

4. 참고 문서

https://kotest.io/docs/quickstart
https://kotest.io/docs/extensions/spring.html

0개의 댓글