Rob Elliot
03/28/2025, 3:54 PMimport io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
@Suppress("UNCHECKED_CAST")
abstract class AbstractSpec(
body: AbstractSpec.() -> Unit,
) : StringSpec(body as StringSpec.() -> Unit) {
fun shared() { }
val sharedProperty = "foo"
}
class ConcreteSpec : AbstractSpec({
"some test" {
shared()
sharedProperty shouldBe "foo"
}
})
That unchecked cast bothers me, and suggests to me that there is probably a better way... could someone point me at the docs I've missed?LeoColman
03/28/2025, 5:46 PMsam
03/28/2025, 8:54 PMRob Elliot
03/28/2025, 10:59 PMI think you're maybe looking for https://kotest.io/docs/framework/test-factories.htmlPossibly... in the past I've used them for reusing tests rather than reusing fixtures. But it probably comes to the same thing if I think hard enough.
Rob Elliot
03/28/2025, 11:01 PMYou can use AbstractSpec as the type in the body lambdaI'm probably being thick but I don't understand what you mean. This doesn't compile:
abstract class AbstractSpec(
body: AbstractSpec.() -> Unit,
) : StringSpec(body) {
fun shared() { }
val sharedProperty = "foo"
}
class ConcreteSpec : AbstractSpec({
"some test" {
shared()
sharedProperty shouldBe "foo"
}
})
sam
03/28/2025, 11:12 PMRob Elliot
03/28/2025, 11:17 PMArgument type mismatch: actual type is 'Function1<AbstractSpec, Unit>', but 'Function1<StringSpec, Unit>' was expected.
sam
03/28/2025, 11:18 PMsam
03/28/2025, 11:18 PMRob Elliot
03/28/2025, 11:26 PMabstract class AbstractSpec(
body: AbstractSpec.() -> Unit,
) : StringSpec() {
fun shared() { }
val sharedProperty = "foo"
init {
body()
}
}
class ConcreteSpec : AbstractSpec({
"some test" {
shared()
sharedProperty shouldBe "foo"
}
})
sam
03/28/2025, 11:27 PMRob Elliot
03/28/2025, 11:30 PMsam
03/28/2025, 11:30 PMthanksforallthefish
03/31/2025, 7:28 AMRob Elliot
03/31/2025, 8:47 AM