在ScalaTest中断言值与给定模式匹配的简明方法

在ScalaTest中断言值与给定模式匹配的简明方法,scala,scalatest,Scala,Scalatest,有没有一种很好的方法来检查模式匹配在ScalaTest中是否成功?邮件列表中提供了一个选项: <value> match { case <pattern> => case obj => fail("Did not match: " + obj) } 匹配{ 案例=> 案例obj=>失败(“不匹配:”+obj) } 但是,它不会组合(例如,如果我想断言一个列表中正好有2个元素与使用Inspectors API的模式匹配)。我可以编写一个匹配器,使用一

有没有一种很好的方法来检查模式匹配在ScalaTest中是否成功?邮件列表中提供了一个选项:

<value> match {
  case <pattern> =>
  case obj => fail("Did not match: " + obj)
}
匹配{
案例=>
案例obj=>失败(“不匹配:”+obj)
}

但是,它不会组合(例如,如果我想断言一个列表中正好有2个元素与使用Inspectors API的模式匹配)。我可以编写一个匹配器,使用一个部分函数文本并在定义后成功(如果我也想在消息中获得模式,它必须是一个宏)。有更好的选择吗?

这可能不是您想要的,但是您可以使用这样的习惯用法编写测试断言

import scala.util.{ Either, Left, Right }
// Test class should extend org.scalatest.AppendedClues

val result = value match {
  case ExpectedPattern => Right("test passed")
  case _ => Left("failure explained here") 
})
result shouldBe 'Right withClue(result.left.get)
这种方法利用了Scala
match
表达式生成一个值这一事实

这里有一个更简洁的版本,它不需要trait
附加线索
,也不需要将匹配表达式的结果赋给
val

(value match {
  case ExpectedPattern => Right("ok")
  case _ => Left("failure reason")
}) shouldBe Right("ok")

我不能百分之百肯定我理解你问的问题,但一个可能的答案是从内到内。鉴于:

case class Address(street: String, city: String, state: String, zip: String)
case class Name(first: String, middle: String, last: String)
case class Record(name: Name, address: Address, age: Int)
你可以写:

inside (rec) { case Record(name, address, age) =>
  inside (name) { case Name(first, middle, last) =>
    first should be ("Sally")
    middle should be ("Ann")
    last should be ("Jones")
  }
  inside (address) { case Address(street, city, state, zip) =>
    street should startWith ("25")
    city should endWith ("Angeles")
    state should equal ("CA")
    zip should be ("12345")
  }
  age should be < 99
}

你提到的最具规模的用户帖子来自2011年。从那时起,我们为这个用例添加了上述语法


比尔

事实上,我认为这比问题中的解决方案更糟糕:失败给出的信息不太有用。这是一个很好的观点。为了解决这个问题,我改进了我的答案,但这个解决方案可能无法满足您“简洁”的目标。
val name = Name("Jane", "Q", "Programmer")
name should matchPattern { case Name("Jane", _, _) => }