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

时间:2014-12-03 17:52:58

标签: scala scalatest

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

<value> match {
  case <pattern> =>
  case obj => fail("Did not match: " + obj)
}

但是,它没有组成(例如,如果我想断言列表的两个元素恰好与使用Inspectors API的模式匹配)。我可以编写一个匹配部分函数文字的匹配器,如果已定义则可以成功(如果我想在消息中获取模式,则必须是一个宏)。还有更好的选择吗?

2 个答案:

答案 0 :(得分:7)

我不是100%确定我理解你问的问题,但一个可能的答案是在Inside trait中使用inside。给出:

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
}

这适用于断言或匹配器。详情如下:

http://www.scalatest.org/user_guide/other_goodies#inside

另一个选项如果您使用匹配器并且只想断言某个值与特定模式匹配,则可以只使用matchPattern语法:

val name = Name("Jane", "Q", "Programmer")
name should matchPattern { case Name("Jane", _, _) => }

http://www.scalatest.org/user_guide/using_matchers#matchingAPattern

您指出的最新用户帖子是从2011年开始的。从那时起,我们为此用例添加了上述语法。

比尔

答案 1 :(得分:1)

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

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表达式产生值的事实。

这是一个更简洁的版本,不需要特征AppendedClues或将匹配表达式的结果分配给val

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