Spring Boot Kotest类的子类化和超类成员的可见性

jxct1oxe  于 2023-10-16  发布在  Spring
关注(0)|答案(1)|浏览(111)

我使用kotest进行SpringBoot集成测试。考虑到我想在许多测试之间重用一些基础设施,我想对公共字段进行抽象,并添加可以在子类测试中调用的助手函数。举例来说:

abstract class AbstractApiIntegrationTest(body: FreeSpec.() -> Unit) : FreeSpec(body) {

    @Value("\${api.http.endpoint}")
    private lateinit var apiEndpoint: String

     fun apiCall(block: RequestSpecification.() -> String): Response {
        return Given {
            cookie(authCookie())
            contentType(ContentType.JSON)

            ...

            body(this.block())
        } When {
            post(apiEndpoint)
        }
    }
})

现在,我想在子类的测试中重用这个helper函数:

class AlertUpdateTest(
    private val dataStorageHelper: DataStorageHelper,
    private val testDataHelper: TestDataHelper,
) : AbstractApiIntegrationTest({
    
    "Should pass" {
       
        apiCall {              <<<<------- issue is on this line
            getRequestBody()
        } Then {
            statusCode(OK.value())
        }
    }
})

然而,apiCall是不可见的,因为它是在类(类成员)的作用域中定义的,但是测试的作用域是FreeSpec。我可以使用一个伴随对象,但它显然不能访问类字段(我从SpringBoot注入值)。
实现这一目标的最佳方式是什么?我知道这不是Kotest本身的问题,而是Kotlin设计的问题。但是Kotest是一个“强迫”Spec风格设计的测试。

c0vxltue

c0vxltue1#

问题是您正在使用“官方”Kotest风格,将您的测试用例传递给FreeSpec的构造函数(或您的子类)。这个构造函数参数只接受一个接受FreeSpec接收器的函数类型,这意味着你不能传递一个接受你的子类作为接收器的lambda。
一种解决方法是使用init块而不是构造函数参数。我怀疑这是,事实上,在早期,过时的Kotest版本中的主要方式,正如Framework页面上的动画图像所示,Testing Styles页面说:“然后在init { }块中,创建测试用例。”所以,继续并执行以下操作:

class AlertUpdateTest(
    private val dataStorageHelper: DataStorageHelper,
    private val testDataHelper: TestDataHelper,
) : AbstractApiIntegrationTest() {

    init {
       "Should pass" {
       
            apiCall {
                getRequestBody()
            } Then {
                statusCode(OK.value())
            }
        }
    }
}

我假设您已经弄清楚了如何让Sping Boot Test为您的apiEndpoint注入值。

相关问题