如何避免Kotest结合SpringBootTest时出现initializationError?
问题描述
我有一个用于验证Spring上下文是否正确加载的JUnit冒烟测试:
@SpringBootTest class ContextLoadJUnit { @Test fun contextLoads() { //empty by design } }
我将其改写为两种Kotest实现:
@SpringBootTest @ApplyExtension(SpringTestExtension::class) class ContextLoadKotestWordSpec : WordSpec({ "context" should { "load with WordSpec" {} } }) @SpringBootTest class ContextLoadKotestFunSpec : FunSpec() { override fun extensions(): List<Extension> { return listOf(SpringExtension) } init { test("context should load with FunSpec") {} } }
将三个测试放在同一文件后,测试通过时能正常显示3个测试全部通过;但测试失败时,Kotest的测试会被包装进initializationError中,看起来只有2个测试失败。需要调整Kotest实现,避免出现initializationError,让三个失败测试都能被正确识别。
解决方案
1. 显式在测试方法中验证上下文
问题根源是Kotest默认单实例策略下,Spring上下文加载可能在Spec初始化阶段触发,失败时被标记为初始化错误。通过在测试方法中显式注入并验证Spring上下文,将错误触发点转移到测试执行阶段:
修改后的WordSpec实现
@SpringBootTest class ContextLoadKotestWordSpec : WordSpec() { @Autowired private lateinit var applicationContext: ApplicationContext init { "context" should { "load with WordSpec" { assertNotNull(applicationContext) } } } override fun extensions(): List<Extension> { return listOf(SpringExtension) } }
修改后的FunSpec实现
@SpringBootTest class ContextLoadKotestFunSpec : FunSpec() { @Autowired private lateinit var applicationContext: ApplicationContext override fun extensions(): List<Extension> { return listOf(SpringExtension) } init { test("context should load with FunSpec") { assertNotNull(applicationContext) } } }
2. 配置Kotest使用Per-Test实例策略
让Kotest和JUnit保持一致的实例化逻辑(每个测试方法创建一个Spec实例),这样上下文加载失败会被识别为测试失败而非初始化错误:
- 方式一:通过配置文件
在项目的src/test/resources/kotest.properties中添加:
kotest.spec.instancepertest=true
- 方式二:通过注解
在Kotest测试类上添加@InstancePerTest注解:
@InstancePerTest @SpringBootTest class ContextLoadKotestWordSpec : WordSpec() { // ... 测试代码 }
3. 移除@ApplyExtension注解(针对WordSpec)
@ApplyExtension注解可能导致扩展提前生效,改用重写extensions()方法的方式注册Spring扩展,和FunSpec保持一致的配置风格。
内容的提问来源于stack exchange,提问作者Piotr Pradzynski
相关产品推荐
相关产品推荐

