【问题标题】:specs2: Multiple matcher expressions (Unit specification)specs2:多个匹配器表达式(单元规范)
【发布时间】:2013-01-15 11:25:40
【问题描述】:

如何检查一个 Matcher 片段中的多个表达式?

例如:

class Foo extends Specification {
   "Retrieving open issues" should {
      "return expected properties with expected data" in     {
         val issue = Bar.openIssues.head

         issue must not beNull
         issue.number must beEqualTo(1) 
         issue.state must beEqualTo("open")
         issue.title must beEqualTo("first issue")
      }
   }
}

报错

[error]  type mismatch;
[error]  found   : Int
[error]  required: org.specs2.matcher.Matcher[Issue]
[error]                         issue.number must beEqualTo(1)

Eric 在this comment 中引用了一个“经典”类型推断问题,但找不到答案。

【问题讨论】:

  • 尝试在这一行添加括号:(issue must not beNull)。这能解决问题吗?
  • 是的。如果您将此作为答案(如果您愿意,请解释为什么这会有所帮助)我会接受。

标签: unit-testing scala specs2


【解决方案1】:

问题出在这一行:

issue must not beNull

因为它是用运算符表示法编写的,所以编译器必须在正确的位置推断点和括号。遵循obj meth argobj.meth(arg) 相同的规则,此行被解释为:

issue.must(not).beNull<missing_arg>

beNull 是在issue.must(not) 的返回值上调用的成员。编译器遵循运算符符号规则并将其视为meth,而issue.must(not) 则视为obj。因为运算符表示法总是要求调用必须具有obj meth arg 的形式,所以在上面的示例中,由于语法无效,编译器会抛出错误。但它没有这样做,因为还有两个进一步的规则:

  1. 在运算符表示法中分隔标识符的空格不仅必须包含空格或制表符,还可以包含单个 (!) 换行符。
  2. 如果找不到arg,则会隐式插入一个空参数列表。

由于 (1),编译器将下一行视为arg

issue.must(not).beNull(
issue.number).must(beEqualTo(1))

这不是代码的解释方式。为了解决这个问题,可以将整个表达式括在括号中:

(issue must not beNull)

或用空行分隔行:

issue must not beNull

issue.number must beEqualTo(1)

两种解决方案都有效,因为 (2) 编译器可以插入一个空参数列表。

注意:如果必须应用 (2),这也称为后缀运算符。在 2.10 中,他们处理警告是因为 - 正如从这个问题中看到的那样 - 它们可能导致棘手的行为。

【讨论】:

  • 其他修复是:issue must not(beNull)issue must not beNull;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-02
  • 1970-01-01
  • 2021-02-15
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
相关资源
最近更新 更多