Kotest类继承时父类成员在子类测试中的可见性问题
Kotest SpringBoot集成测试中父类成员函数访问问题的解决方案
方案一:调整测试块的接收者类型
核心思路是修改父类构造函数的lambda参数类型,让测试块的作用域指向父类实例而非FreeSpec,这样就能直接访问父类的成员函数。
父类修改代码
abstract class AbstractApiIntegrationTest(body: AbstractApiIntegrationTest.() -> Unit) : FreeSpec() { @Value("\${api.http.endpoint}") private lateinit var apiEndpoint: String init { // 以当前父类实例为接收者执行测试块 body() } fun apiCall(block: RequestSpecification.() -> String): Response { return Given { cookie(authCookie()) contentType(ContentType.JSON) body(this.block()) } When { post(apiEndpoint) } } }
子类使用代码
class AlertUpdateTest( private val dataStorageHelper: DataStorageHelper, private val testDataHelper: TestDataHelper, ) : AbstractApiIntegrationTest({ "Should pass" { apiCall { // 现在可直接调用父类成员函数 getRequestBody() } Then { statusCode(OK.value()) } } })
这种方式最贴合Kotlin的作用域设计,代码简洁自然,Spring注入的实例字段也能正常工作。
方案二:保存父类实例引用
如果不想修改原有构造函数的lambda类型,可以在父类中定义一个指向自身的引用,子类测试块通过该引用访问成员函数。
父类修改代码
abstract class AbstractApiIntegrationTest(body: FreeSpec.() -> Unit) : FreeSpec(body) { @Value("\${api.http.endpoint}") private lateinit var apiEndpoint: String protected lateinit var self: AbstractApiIntegrationTest init { self = this } fun apiCall(block: RequestSpecification.() -> String): Response { return Given { cookie(authCookie()) contentType(ContentType.JSON) body(this.block()) } When { post(apiEndpoint) } } }
子类使用代码
class AlertUpdateTest( private val dataStorageHelper: DataStorageHelper, private val testDataHelper: TestDataHelper, ) : AbstractApiIntegrationTest({ "Should pass" { self.apiCall { // 通过self引用访问父类成员 getRequestBody() } Then { statusCode(OK.value()) } } })
该方案无需调整原有构造逻辑,适合需要保留FreeSpec原始作用域的场景。
内容的提问来源于stack exchange,提问作者redhead
相关产品推荐
相关产品推荐

