在ScalaTest中组合测试夹具的更好方法

Vik*_*dya 6 scala composition scalatest

我们有使用贷款模式的测试装置.利用此模式创建运行测试所需的"种子数据".当测试依赖于数据时例如以下

"save definition" should {
"create a new record" in withSubject { implicit subject =>
  withDataSource { implicit datasource =>
    withFormType { implicit formtype =>

        val definitn = DefinitionModel(-1, datasource.id, formtype.id, subject.role.id, Some(properties))
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

其中withSubject,withDataSource,withFormType是测试夹具返回subject,dataSource,formType从数据库数据分别.withDataSource夹具需要subject隐含.建筑DefinitionModel要求datasource.idformtype.id.所以根据测试的数据要求调用这样的数据构建器夹具会产生很多嵌套的夹具情况.有没有更好的方法来"组合"/构建这样的灯具?

Luk*_*asz 5

@Nader Hadji Ghanbari 给出的答案仍然成立。我想补充一点,自 scalatest 3.xx 版本以来,特征更改了名称。从迁移指南复制:

覆盖 withFixture 的 Mixin 特征

4) 在 3.0.0 中,withFixture 方法已从 Suite 移至新特征 TestSuite。这样做是为了在 AsyncTestSuite 中为具有不同签名的 withFixture 方法腾出空间。如果您将 withFixture 方法分解为单独的“suite mixin”特征,则需要将“Suite”更改为“TestSuite”,将“SuiteMixin”更改为“TestSuiteMixin”。例如,考虑到 2.2.6 中的这个特征:

trait YourMixinTrait extends SuiteMixin { this: Suite =>
 abstract override def withFixture(test: NoArgTest): Outcome = {
   // ...
 }
}
Run Code Online (Sandbox Code Playgroud)

您需要添加“Test”前缀,如下所示:

trait YourMixinTrait extends TestSuiteMixin { this: TestSuite =>
 abstract override def withFixture(test: NoArgTest): Outcome = {
   // ...
 }
}
Run Code Online (Sandbox Code Playgroud)


Nad*_*ari 4

特征

trait是你的朋友。trait构图是很好涵盖的要求之一。

作曲特征

来自Scala 测试文档

通过堆叠特征来组合灯具

在较大的项目中,团队通常会得到测试类需要的不同组合的几种不同的装置,并且可能以不同的顺序初始化(和清理)。在 ScalaTest 中实现此目的的一个好方法是将各个固定装置分解为可以使用可堆叠特征模式组合的特征。例如,可以通过将 withFixture 方法放置在多个特征中,每个特征都调用 super.withFixture 来完成此操作。

例如,您可以定义以下trait内容

trait Subject extends SuiteMixin { this: Suite =>

  val subject = "Some Subject"

  abstract override def withFixture(test: NoArgTest) = {
    try super.withFixture(test) // To be stackable, must call super.withFixture
    // finally clear the context if necessary, clear buffers, close resources, etc.
  }
}

trait FormData extends SuiteMixin { this: Suite =>

  val formData = ...

  abstract override def withFixture(test: NoArgTest) = {
    try super.withFixture(test) // To be stackable, must call super.withFixture
    // finally clear the context if necessary, clear buffers, close resources, etc.
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以trait通过将它们混合到你的测试上下文中:

class ExampleSpec extends FlatSpec with FormData with Subject {

    "save definition" should {
        "create a new record" in {

            // use subject and formData here in the test logic            

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

可叠加的特质

有关Stackable Traits Pattern的更多信息,您可以参考这篇文章