Kotest Engine with Spring Framework and ...

Kotest Engine with Spring Framework and getProjectWideFailFast

Mar 15, 2024

I'm always very interested in seeing how Kotlin works and the different ways we can use Kotlin for different purposes. This has a very broad range and of course the hot-topics are usually co-routines, reactive programming and the use of all the sugar coding Kotlin provides. Another thing getting more commonly used are Kotest assertions in testing which makes heavy use of infix functions and extension functions in order to provide things like shouldBe or shouldHave among many other assertions. For testing, we can always use the Kotest engine instead of just the Jupiter engine. Jupiter in itself is a testing engine but used in combination with Kotest, it can provide a different way to make tests like this one:

@SpringBootTest
@AutoConfigureWebTestClient
@ContextConfiguration(classes = [(Service::class)])
class HelloTestMockk : StringSpec() {

 override fun extensions() = listOf(SpringExtension)

 @MockkBean(relaxed = true)
 lateinit var service: Service

 init {
 "should have autowired the service" {
 service shouldNotBe null
 }
 }
}

As you can see it gives a Scala like test look and feel. This was very possible to do in my project up until Kotest made an update to version 5.2.1. When Dependabot opened a PR for my project at https://github.com/jesperancinha/jeorg-spring-master-5-test-drives, I got the following error:

java.lang.NoSuchMethodError: 'boolean io.kotest.core.config.ProjectConfiguration.getProjectWideFailFast()'
	at io.kotest.engine.ConcurrentTestSuiteScheduler$schedule$8$1$2.invokeSuspend(ConcurrentTestSuiteScheduler.kt:65)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at io.kotest.common.RunBlockingKt.runBlocking(runBlocking.kt:3)
	at io.kotest.engine.launcher.MainKt.main(main.kt:34)

'boolean io.kotest.core.config.ProjectConfiguration.getProjectWideFailFast()

I reached their team about this and the only way they could help me was to tell me that there had to be something wrong with the versions. This was a very important lead/clue. Long story short, I found out in the effective POM that I my project was still injecting, for some reason, version 5.0.0. of kotest-framework-api-jvm. If you don't know this, the effective POM is not the same as the POM you configure and type into the project. The effective POM is a POM that you can generate locally that lays out what you are effectively using in your project. The only way I found out how to solve this problem was to insert explicitly version 5.2.1 of this library in my project:

<dependency>
 <groupId>io.kotest</groupId>
 <artifactId>kotest-framework-api-jvm</artifactId>
 <version>${kotest.version}</version>
 <scope>test</scope>
</dependency>

Where does version 5.0.0 of this library comes/came from, I still do not know, but if you ever find something like this in your project, then I hope my post helps you out! You can find my project here: https://github.com/jesperancinha/jeorg-spring-master-5-test-drives. The ticket I've opened to them here: https://github.com/kotest/kotest-extensions-spring/issues/22.

Enjoy this post?

Buy João Esperancinha a coffee

More from João Esperancinha