Write a BehaviorSpec test and explain how given/when/then map to nesting, including how Kotest avoids clashing with Kotlin's `when` keyword.
answer
- given = context, when = action, then = assertion
- Only then blocks are real tests
- `when` is a Kotlin keyword → backtick it
- Capitalized Given/When/Then avoid backticks
- And() adds extra branches
basics
~10 sBehaviorSpec groups tests as given (a context), when (an action), then (the assertion). Because when is a Kotlin keyword, you either backtick it or use the capitalized When alias.
solid answer
~40 s`BehaviorSpec` gives you a BDD layout: `given("...")` describes the starting context, `` `when`("...") `` describes the action under test, and `then("...")` holds the actual assertion. They nest: a `given` contains `when` blocks, each containing `then` leaves — only `then` blocks are real test cases. Because `when` is a hard Kotlin keyword, the lowercase form must be backticked: `` `when`("...") { } ``. To avoid that, Kotest provides capitalized aliases `Given`/`When`/`Then` that read cleanly without backticks. `And` variants (`xthen`, `Then`/`And`) also exist for extra context lines. Bodies live in an `init { }` block or the constructor lambda. The nesting builds readable hierarchical test names in reports.
code
kotlin · 14 linesimport io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.shouldBe
class WithdrawTest : BehaviorSpec({
Given("an account with balance 100") {
var balance = 100
When("30 is withdrawn") {
balance -= 30
Then("the balance is 70") {
balance shouldBe 70
}
}
}
})go deeper
Knows the given/when/then triad and that it reads like BDD.
Writes a correct nested BehaviorSpec, handles the when keyword via backticks or aliases, and knows only then is a leaf.
Explains hierarchical naming in reports and when BDD layout aids acceptance/spec-by-example tests.
Weighs BehaviorSpec readability vs verbosity for the team and aligns it with living-documentation/BDD practices.
## BehaviorSpec structure `BehaviorSpec` implements Behavior-Driven Development (BDD). Tests are organized into three nested levels: - **given** — the precondition/context ("given a user with an empty cart"). - **when** — the action being exercised ("when an item is added"). - **then** — the observable outcome and the actual assertions ("then the cart size is 1"). Only the **then** blocks are leaf test cases that pass or fail; `given` and `when` are containers that organize and name them. ## The `when` keyword problem `when` is a reserved Kotlin keyword (used for `when` expressions). So calling the lowercase DSL function requires **backticks**: `` `when`("...") { } ``. To avoid the awkward backticks, Kotest also exposes **capitalized aliases**: `Given`, `When`, `Then` (and `And`). These are ordinary identifiers and read fluently. ```kotlin import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe class CartTest : BehaviorSpec({ given("an empty cart") { val cart = mutableListOf<String>() `when`("an item is added") { cart.add("book") then("the cart has one item") { cart.size shouldBe 1 } } } }) // Capitalized aliases avoid backticks: class CartTest2 : BehaviorSpec({ Given("an empty cart") { val cart = mutableListOf<String>() When("an item is added") { cart.add("book") Then("the cart has one item") { cart.size shouldBe 1 } } } }) ``` ## Reporting Kotest concatenates the nesting into a hierarchical, human-readable test name in output (e.g. "Given an empty cart When an item is added Then the cart has one item"), which is the payoff of BDD-style nesting. ## Notes - `And` (`And("...")`) lets you add additional context branches under given/when. - The same engine/matchers apply; BehaviorSpec is purely a layout choice.
- Which blocks in a BehaviorSpec actually count as test cases?Only the then/Then blocks are leaf tests that pass or fail; given and when are organizing containers.
- Why does the lowercase `when` need backticks but `When` doesn't?`when` is a reserved Kotlin keyword so it must be escaped with backticks; `When` is a normal identifier alias Kotest provides.
Given/When/Then is like a recipe: ingredients on the counter (given), the cooking step (when), and tasting the result (then).
saying these in an interview costs you the question
- Putting assertions in given/when instead of then
- Claiming lowercase when works without backticks
- Not knowing capitalized aliases exist
- Thinking given/when blocks are independently runnable tests