Introduction to Spek
Spek is a specification framework for Kotlin that allows developers to write clear, concise, and idiomatic unit tests. Spek provides a flexible API for writing and organizing tests in a more human-readable style. This guide will introduce you to Spek and provide dozens of useful API explanations along with code snippets.
Getting Started with Spek
To start using Spek, add the following dependencies to your project’s build.gradle.kts
:
dependencies { testImplementation("org.spekframework.spek2:spek-dsl-jvm:2.0.16") testRuntimeOnly("org.spekframework.spek2:spek-runner-junit5:2.0.16") }
Ensure that you also use the JUnit platform for running tests:
tasks.withType{ useJUnitPlatform() }
Writing Your First Test
Spek’s API encourages writing tests in a structured and readable format. Here’s an example of a basic test:
import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe import kotlin.test.assertEquals object CalculatorSpec : Spek({ describe("A calculator") { val calculator = Calculator() context("addition") { it("should return the correct sum") { assertEquals(2, calculator.add(1, 1)) } } } })
Organizing Your Tests
Spek allows you to organize your tests in multiple nested scopes. Here’s a comprehensive example:
import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe import kotlin.test.assertTrue object StringSpec : Spek({ describe("A string") { val subject = "Kotlin Spek Framework" context("when checking its length") { it("should be greater than 10") { assertTrue(subject.length > 10) } } context("substring operations") { it("should return a valid substring") { val substring = subject.substring(7, 11) assertEquals("Spek", substring) } } } })
Mocking Dependencies with Spek
Spek integrates well with Kotlin’s popular mocking libraries. Here’s an example using mockk
:
import io.mockk.every import io.mockk.mockk import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe import kotlin.test.assertEquals class UserService(val repository: UserRepository) interface UserRepository { fun getUser(id: Int): User } data class User(val id: Int, val name: String) object UserServiceSpec : Spek({ val repository = mockk() val userService = UserService(repository) describe("User service") { context("getUser") { val user = User(1, "John Doe") every { repository.getUser(1) } returns user it("should return the correct user") { assertEquals(user, userService.getUser(1)) } } } })
Creating a Simple Application with Spek Tests
Let’s take a look at a simple example of a Calculator application tested with Spek:
class Calculator { fun add(a: Int, b: Int): Int { return a + b } fun subtract(a: Int, b: Int): Int { return a - b } } object CalculatorSpec : Spek({ describe("A calculator") { val calculator = Calculator() context("addition") { it("should return the correct sum") { assertEquals(5, calculator.add(2, 3)) } } context("subtraction") { it("should return the correct difference") { assertEquals(1, calculator.subtract(3, 2)) } } } })
This Calculator class is a simple example of how you could structure your application and test its core functionalities using Spek.
Integrating Spek into your development process will help you write unit tests that are both maintainable and fun to read, ensuring your code remains robust and reliable.
Hash: e1b4e88e1eae11ed29bac270ed5bd4f133b4dd43091ce3e6417607f5b7938fc7