Part 5 · 1 chapters · ~8 min

Tooling and Testing

Gradle with the Kotlin DSL and version catalogs, IntelliJ, JUnit 5 and Kotest, MockK, testing coroutines with runTest and virtual time, Testcontainers for Postgres, property-based tests, ktlint, detekt and Kover, and CI.

6

Deterministic tests for async code

code
@Test fun `retries a timed-out rail call three times then marks unknown`() = runTest {
    val rail = mockk<Rail>()
    coEvery { rail.send(any()) } throws TimeoutException()
    val result = PayoutService(rail, repo).submit(payout)          // contains delay(2_000 * 2^n) backoff
    assertEquals(PayoutState.UNKNOWN, result.state)                // runs instantly on virtual time
    coVerify(exactly = 3) { rail.send(any()) }
}

class LedgerProps : StringSpec({
    "postings always sum to zero" { checkAll(Arb.long(1L..10_000_000L), Arb.long(0L..5_000L)) { amount, fee ->
        postingsFor(Kobo(amount), Kobo(fee)).sumOf { it.amount.value } shouldBe 0L } }
})

// Testcontainers: a real Postgres per test class
@Container val pg = PostgreSQLContainer("postgres:16")
TOOLING AND TESTING
the Kotlin toolbox
Gradle (Kotlin DSL)build.gradle.kts: typed buildscripts.IntelliJ IDEAFirst-class IDE from thelanguage's creator, JetBrains.JUnit 5 / KotestTests in plain JUnit, or Kotest'sspecs and property tests.MockKMocking designed for Kotlin (finalclasses, coroutines).kotlinx-coroutines-testrunTest with virtual time: delaysskip instantly.ktlint, detekt, KoverFormatting, static analysis,coverage.
swipe the figure sideways, or tap expand for full screen
1/4
builds
Gradle with the Kotlin DSL is the standard build; Maven works too. Version catalogs (libs.versions.toml) keep dependencies consistent across modules.
Gradle Kotlin DSLversion catalogs