TIL(Today I Learned)

TIL - Kotest 테스트 코드 작성하기

Happy._. 2024. 6. 10. 23:19

테스트 수행 전 다음과 같이 의존성을 추가한다.

val kotestVersion = "5.5.5"
val mockkVersion = "1.13.8"

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

 

IntelliJ Plugins에 Kotest도 설치해 준다.

 

위 설정을 모두 마친 후 테스트 코드를 작성한다. 

다음은 User Entity 생성자 테스트 코드이다.

class TodoEntityTest : BehaviorSpec({

    val user = User.from( // Todo 작성 시 User가 포함되어야 하므로 작성
        CreateUserRequest(
            email = "test@naver.com",
            nickname = "yoyo",
            password = "1234"
        ), joinType = "EMAIL"
    )

    Given("Todo Information") {
        val title = "title"
        val content = "content"
        val writer = "writer"

        When("Todo Constructor") {
            val result = Todo.from( // private constructor
                CreateTodoRequest(
                    title = title,
                    content = content,
                    writer = writer
                ),
                user = user
            )

            then("Result Should be") {
                result.title shouldBe title
                result.content shouldBe content
                result.writer shouldBe writer
            }
        }
    }
})

 

이번에는 Validation을 사용해 다음 DTO의 필드 값을 검증한다.

data class CreateTodoRequest(
    @field:Size(min = 1, max = 200, message = "Title must be between 1 and 200")
    val title: String,
    @field:Size(min = 1, max = 1000, message = "Content must be between 1 and 1000")
    val content: String,
    val writer: String,
)

 

위 DTO에서 어노테이션을 지정한 title과 content가 유효한 값이 아닐 때 반환되는 객체의 message를 통해 DTO에서 지정한 message를 확인할 수 있다.

class TodoEntityTest(
) : BehaviorSpec({
    val validator: Validator = Validation.buildDefaultValidatorFactory().validator

    Given("User Information") {
        val title = "" 
        val content = "" 
        val writer = "writer"

        When("Todo with empty title") {
            val result = validator.validate(
                CreateTodoRequest(
                    title = title,
                    content = content,
                    writer = writer
                )
            )

            result.forEach { println(it.message) }
            // Title must be between 1 and 200
            // Content must be between 1 and 1000
        }
    }
})

 

다음은 TodoService를 테스트하는 코드이다.

TodoService에서 사용하는 Repository와 Service는 mokk를 사용해 mock객체로 만들어 준다.

class TodoServiceTests : BehaviorSpec({

    val todoRepository: TodoRepository = mockk<TodoRepository>()
    val userRepository: UserRepository = mockk<UserRepository>()
    val userService: UserService = mockk<UserService>()
    
    val savedTodo = Todo.from(
        CreateTodoRequest(
            title = "title",
            content = "content",
            writer = "writer"
        ),
        user = User.from(
            CreateUserRequest(
                email = "test@naver.com",
                nickname = "yoyo",
                password = "1234"
            ), joinType = "EMAIL"
        )
    )

    savedTodo.id = 1L // 테스트를 위해 Todo Entity의 id를 val -> var로 변경

    every { todoRepository.findByIdOrNull(1L) } returns savedTodo
    every { todoRepository.findByIdOrNull(10L) } returns null

    val todoService = TodoServiceImpl(todoRepository, userRepository, userService)

    Given("saved todo id") {
        val targetTodoId = 1L

        When("todoRepository findById") {
            val result = todoService.getTodoById(targetTodoId)

            Then("result should not be null") {
                result shouldNotBe null
                result.let {
                    it.id shouldBe savedTodo.id
                    it.title shouldBe savedTodo.title
                    it.content shouldBe savedTodo.content
                    it.writer shouldBe savedTodo.writer
                }
            }
        }
    }
})