2013-01-15 26 views
4

如何在一個Matcher片段中檢查多個表達式?specs2:多個匹配表達式(單元規範)

例如:

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) 

埃裏克引用了 「經典」 類型推理問題this comment,但無法找到答案。

+1

嘗試在這一行添加括號:'(問題不能是空)'。這是否解決了這個問題? – sschaef

+0

是的。如果你讓這個答案(並解釋爲什麼這有助於,如果你願意),我會接受它。 – Eran

回答

4

問題就出在這行:

issue must not beNull 

因爲它是寫在操作符號編譯器必須在正確的位置推斷點和括號。遵循的原則是obj meth arg相同obj.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中,他們會提出警告,因爲 - 正如人們可以看到這個問題 - 他們會導致棘手的行爲。

+3

其他的修正是:'不能(beNull)'或'issue不能是null';' – Eric