[Spring Boot] Kotest + Mockk

Spring Boot

Language :

Kotest

Open source testing framework to test and validate kotlin code

It provides 10 test layouts to test various situations. (Link)

Mockk

Kotlin Mocking Framework

Write a test code based on Domain Specific Language (DSL).

  • Mocking: A simulated object. A test object that virtually replaces an external service or module.

Example

Tested services using Behavior Driven Development (BDD) method, BehaviorSpec

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 → Search 'Kotest' → Install

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 {
        // Account Inquiry
        val user = userRepository.findByEmail(email) ?: throw RuntimeException("email? $email")
        // Confirm password
        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 dependency object declaration
    val userRepository = mockk<UserRepository>()
    // Test Data Declaration
    var email: String
    var password: String

    Given("Test Login") {
        email = "test@gmail.com"
        password = "test-password"

        // Inject dependency objects into UserService
        val service = withContext(Dispatchers.IO) {
            UserServiceImpl(userRepository)
        }

        When("If you enter a valid account") {
            // Set account lookup result value arbitrarily
            every { userRepository.findByEmail(any()) } returns user
            Then("Login Successful") {
                val result = service.login(email = email, password = password)
                // Verification of the result value
                result shouldNotBe null
                result shouldBe "session-key"
            }
        }

        When("If you enter an invalid account") {
            And("If you enter an email that does not exist") {
                every { userRepository.findByEmail(any()) } returns null

                Then("An exception occurs") {
                    val result = shouldThrow<RuntimeException> {
                        service.login(email = email, password = password)
                    }
                    result.message shouldBe "email? $email"
                }
            }
            And("If you enter the wrong password") {
                password = "test-password-1"
                every { userRepository.findByEmail(any()) } returns user

                Then("An exception occurs") {
                    shouldThrow<PasswordFailException> {
                        service.login(email = email, password = password)
                    }
                }
            }
        }
    }
}) {
    companion object {
        val user = User(
            id = 1L,
            email = "test@gmail.com",
            password = "test-password"
        )
    }
}

Run the test

Press the green arrow on the left with the Kotest Plugin to run the test in each step.

If it runs normally from Given, the following results will be obtained.

intellij_kotest_given.png

Full code link

민갤

Back-End Developer

백엔드 개발자입니다.