【问题标题】:kotest nested spec in describe clausedescribe 子句中的 kotest 嵌套规范
【发布时间】:2020-05-27 10:56:52
【问题描述】:

我已经开始使用 kotest:4.0.5 (kotlintest) 并且遇到了嵌套在 describe 子句中的 stringSpec 函数的问题。

例子:

class SellerTest : DescribeSpec({

    describe("Registration") {
        context("Not existing user") {
            include(emailValidation()
        }
    }
})

fun emailValidation() = stringSpec {
    "Email validation" {
        forAll(
            row("test.com"),
            row("123123123123123")
        ) { email ->
            assertSoftly {
                val exception =
                    shouldThrow<ServiceException> { Email(email) }

            }
        }
    }
}

如果include(emailValidation())describe 子句之外,则可以正常工作。

您知道如何在子句中嵌套规范/功能吗?

【问题讨论】:

    标签: kotlin kotlintest kotest


    【解决方案1】:

    您只能在顶层使用include。这是工厂测试(include 关键字的用途)实现方式的一部分(可能会在未来的版本中放宽)。

    不过你可以把整个东西搬进工厂。

    class SellerTest : DescribeSpec({
      include(emailValidation)
    })
    
    val emailValidation = describeSpec {
    
        describe("Registration") {
            context("Not existing user") {
                forAll(
                    row("test.com"),
                    row("123123123123123")
                ) { email ->
                    assertSoftly {
                        val exception =
                            shouldThrow<ServiceException> { Email(email) }
                    }
                }
            }
        }
    }
    

    你可以参数化任何你想要的命名,因为这只是字符串,例如:

    fun emailValidation(name: String) = describeSpec {
        describe("Registration") {
            context("$name") {
            }
        }
    }
    

    如果您不进行参数化,那么拥有测试工厂就没有什么意义了。只需声明测试内联 IMO。

    【讨论】:

    • 谢谢,老实说这不是我梦寐以求的^^。我以为有人会有神奇的解决方案。希望将来会有所改变。
    • 你想要达到的目标与我展示的相比。也许还有其他方法可以获得相同的结果。
    • 电子邮件验证是注册过程的一部分,所以不能这样。我想将它嵌套在注册描述中。但如果它不可能,那么可能会将其包括在范围之外。
    【解决方案2】:

    对于嵌套的include,你可以像这个例子那样实现你自己的工厂方法:

    class FactorySpec : FreeSpec() {
        init {
            "Scenario: root container" - {
                containerTemplate()
            }
        }
    }
    
    /** Add [TestType.Container] by scope function extension */
    suspend inline fun FreeScope.containerTemplate(): Unit {
        "template container with FreeScope context" - {
            testCaseTemplate()
        }
    }
    
    /** Add [TestType.Test] by scope function extension */
    suspend inline fun FreeScope.testCaseTemplate(): Unit {
        "nested template testcase with FreeScope context" { }
    }
    
    

    注意传递给containerTemplatetestCaseTemplate的扩展函数的Scope

    输出:

    Scenario: root container
       template container with FreeScope context
           nested template testcase with FreeScope context
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      相关资源
      最近更新 更多