2014-12-03 45 views
9

有一種很好的方式來檢查模式匹配在ScalaTest中成功嗎?一個選項是在scalatest-users郵件列表給出:簡明的方式來聲明一個值匹配ScalaTest中給定的模式

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

但是,它不組成(例如,如果我想斷言列表的恰好2個元件使用檢查員API匹配的模式)。我可以編寫一個獲取部分函數文字的匹配器,如果它被定義了,它就會成功(如果我想在消息中獲取模式,它也必須是一個宏)。有更好的選擇嗎?

回答

5

我不是100%確定我明白你問的問題,但是一個可能的答案是從Inside特徵中使用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

您指出的scalatest-users帖子是從2011年開始的。從那時起,我們爲此用例添加了上述語法。

比爾

0

這可能不是您想要的,但您可以使用這樣的成語編寫測試斷言。

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") 
+0

其實,我覺得這比在問題解決糟糕:未能給出一個不太有用的消息。 – 2015-02-04 06:15:13

+0

這是一個很好的觀點。我已經改進了解決該問題的答案,但該解決方案可能無法實現「簡潔」的目標。 – 2015-02-04 17:15:40

相關問題