如何为组合集合定义`LoneElement`和`Emptiness`?

时间:2018-02-06 16:11:50

标签: scala scalatest

我有一个案例类,它是一个简单的集合包装器:

final case class Foo(foos: Seq[Int])

在我的测试中,我想对Foo#foos的空虚和孤独元素做出断言。我目前正在通过直接访问Foo#foos来解决问题:

foo.foos shouldBe empty

foo.foos.loneElement should===(1)

这有效,但打破了封装。

我查看过最新的文档,但是没有找到在合作伙伴之外定义这些运算符的方法。

我该如何定义它们?在测试中内联它们的奖励点。

1 个答案:

答案 0 :(得分:1)

定义一些隐含来处理Foo(在test - 目录中,而不是在main源代码树中):

import org.scalatest.enablers.Emptiness

trait FooImplicits {

  case class FooLoneElementWrapper(wrapped: Foo) {
    def loneElement: Int = {
      assert(wrapped.foos.size == 1)
      wrapped.foos(0)
    }
  }
  implicit def fooCanHazLoneElement(foo: Foo) = FooLoneElementWrapper(foo)
  implicit object FooEmptiness extends Emptiness[Foo] {
    def isEmpty(foo: Foo) = foo.foos.isEmpty
  }

}

现在只需将特质FooImplicits混合到您想要使用它的FlatSpec中:

import org.scalatest._

class FooSpec extends FlatSpec with Matchers with FooImplicits {

  "Foo" should "be empty when it's empty" in {
    Foo(Seq()) shouldBe empty
  }

  it should "have loneElements" in {
    val x = Foo(Seq(1))
    x.loneElement should equal (1)
  }
}

利润:

[info] Foo
[info] - should be empty when it's empty
[info] - should have loneElements

请注意FooImplicits可以在package Foo main test中定义Foo,即使 <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.9.0</version> </dependency> 完全不同 XmlMapper xmlMapper = new XmlMapper(); JsonNode node = xmlMapper.readTree(sb.toString().getBytes()); - 源代码树。这样,它就可以访问{{1}}的包可见成员。