1 year ago

#77532

test-img

Bryan

In kotest is there a way to have a "before" hook run once for a TestContainer it's in?

I'm trying to use Kotest to write nested tests that have hooks that only run once per nest level. This is how mocha works in JavaScript and how RSpec works in ruby. In mocha the function is called before. I tried using beforeContainer but it runs once for each nested container instead of just once for the entire container including any nested containers within that parent container. This is hard to explain, so below is a set of tests that I would expect to pass, if a before method existed in kotest that behaved like mocha's or RSpec's. In short, each before method should only be called once, and only when tests in its container run (e.g., the before method inside "nested level 2" shouldn't run until the tests in "nested level 1" have run).

package foo.bar

import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.shouldBe

class WidgetTest : DescribeSpec({
    var foo = "initial"
    var counterOne = 0
    var counterTwo = 0
    var counterThree = 0

    before {
        foo = "bar"
        counterOne++
    }

    it("foo should be bar") {
        foo shouldBe "bar"
        counterOne shouldBe 1
    }

    it("beforeSpec should have been called only once") {
        foo shouldBe "bar"
        counterOne shouldBe 1
    }

    it("counterTwo should be 0") {
        counterTwo shouldBe 0
    }

    it("counterThree should be 0") {
        counterThree shouldBe 0
    }

    describe("nested level 1") {
        before {
            foo = "buzz"
            counterTwo++
        }

        it("foo should be buzz") {
            foo shouldBe "buzz"
        }

        it("and counterOne should be 1") {
            counterOne shouldBe 1
        }

        it("and counterTwo should be 1") {
            counterTwo shouldBe 1
        }

        describe("nested level 2") {
            before {
                foo = "jazz"
                counterThree++
            }

            it("foo should be jazz") {
                foo shouldBe "jazz"
            }

            it("and counterOne should be 1") {
                counterOne shouldBe 1
            }

            it("and counterTwo should be 1") {
                counterTwo shouldBe 1
            }

            it("and counterThree should be 1") {
                counterThree shouldBe 1
            }
        }
    }
})

I can get close to what I want if I make the first before a beforeSpec and the other two beforeContainer (and move them above each nested container), but then counterTwo gets incremented twice: once for "nested level 1" and once for "nested level 2". I'm not sure if I'm just doing something wrong or if this capability simply doesn't exist in kotest.

kotlin

kotlintest

kotest

0 Answers

Your Answer

Accepted video resources