Scala 将贴图与specs2匹配

Scala 将贴图与specs2匹配,scala,specs2,Scala,Specs2,假设我有一个函数foo:()->Map[String,a],其中a是trait trait A { def x: Int, def y: Int } 现在我需要编写一个specs2spec,以确保foo返回一个包含两个预期对的映射。请注意,我不知道值的实际类型 不幸的是,在这种情况下,我没有弄清楚如何使用matcher,因此我在写: "test foo" in { val m = foo() def test(a: A, x: Int, y: Int) = (a.x must_==

假设我有一个函数
foo:()->Map[String,a]
,其中
a
是trait

trait A { def x: Int, def y: Int }
现在我需要编写一个
specs2
spec,以确保
foo
返回一个包含两个预期对的映射。请注意,我不知道值的实际类型

不幸的是,在这种情况下,我没有弄清楚如何使用matcher,因此我在写:

"test foo" in {
   val m = foo()
   def test(a: A, x: Int, y: Int) = (a.x must_== 0) and (a.y must_== 1)
   test(m("key1"), 0, 1)  
   test(m("key2"), 3, 5)
 }
这个代码很难看。你建议怎么改


我想我应该为
a
和新的
havePairs
匹配器编写一个自定义匹配器,它将使用这个
a
-matcher来匹配pairs值。这有意义吗?

通常你会使用havePairs,因为你不能使用基于hashCode的normalcontains方法

Scala对于类比较不支持开箱即用的结构等式。如果您使用案例类,您将获得该功能,并且可以使用havePairs

如果你需要支持特质,我担心你不得不为你想要支持和测试的每个案例编写平等意味着什么

class ExampleSpec extends Specification{override def is: Fragments = s2"""
Generated map contains data                            $caseClassTest
works also for Trait                                   $traitTest
"""

  trait A { def x: Int ; def y: Int }

  // case class, exactly the same as Trait A
  case class CaseA(x: Int, y:Int) extends A

  // generates a Map with Traits on calling apply on function
  def generateTraitMap : () => Map[String,A] = () => Map(
    "k1" -> new A{ def x = 1 ; def y = -1 },
    "k2" -> new A{ def x = 0 ; def y = 42 }
  )

  // generates a Map with CaseClasses on calling apply on function
  def generateCaseClassMap : () => Map[String,A] = () => Map(
    "k1" -> CaseA(1, -1),
    "k2" -> CaseA(0,42)
  )

  // Test with case classes works with havePairs out of the box
  def caseClassTest = generateCaseClassMap() must havePairs(
    "k1" -> CaseA(1, -1),
    "k2" -> CaseA(0,42)
  )

  // testing Traits needs some plumbing, and will give poor error feedback
  def traitTest = {
    val data = generateTraitMap()
    def testStructuralEquality(a: A, b: A) = 
      List[A => Int]( _.x, _.y ).forall(f => f(a) == f(b) )

    val testData = Map(
      "k1" -> new A{ def x = 1 ; def y = -1 },
      "k2" -> new A{ def x = 0 ; def y = 42 }
    )

    testData.forall{ case (k,v) => testData.contains(k) && testStructuralEquality(v, testData(k)) } must beTrue

  }

}

测试(映射(“键1”),0,1)没有有效的scala代码。粘贴时是否遗漏了某些内容?定义val映射很危险,因为它可能会与常用的函数映射混淆。@AndreasNeumann,谢谢。修复了。您希望测试对特征a有效还是将a作为类型参数?我只想测试特征a。不需要类型参数。