2014-12-03 4 views
9

Gibt es eine gute Möglichkeit zu überprüfen, ob eine Musterübereinstimmung in ScalaTest erfolgreich ist? Eine Option wird in scalatest-users Mailing-Liste gegeben:Kurzer Weg, um einen Wert zu bestätigen, stimmt mit einem gegebenen Muster in ScalaTest überein.

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

Es ist jedoch nicht komponiert nicht (zum Beispiel, wenn ich, dass genau zwei Elemente einer Liste entsprechen das Muster unter Verwendung von Inspektoren API behaupten will). Ich könnte einen Matcher schreiben, der ein Teilfunktionsliteral nimmt und Erfolg hat, wenn es definiert ist (es müsste ein Makro sein, wenn ich auch das Muster in der Nachricht bekommen möchte). Gibt es eine bessere Alternative?

Antwort

5

Ich bin nicht 100% sicher, dass ich verstehe die Frage Sie fragen, aber eine mögliche Antwort ist innerhalb von innen Merkmale zu verwenden. Gegeben:

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) 

Sie schreiben:

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 
} 

, dass beide Werke für Behauptungen oder Matcher. Details hier:

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

Die andere Option, wenn Sie Matcher verwenden und wollen einfach nur behaupten, dass ein Wert ein bestimmtes Muster entspricht, können Sie einfach die matchPattern Syntax:

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

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

Der Beitrag von scalatest-users, auf den Sie hingewiesen haben, stammt aus dem Jahr 2011. Wir haben die obige Syntax für diesen Anwendungsfall seither hinzugefügt.

Bill

0

Dies ist möglicherweise nicht genau das, was Sie wollen, aber Sie könnten Ihre Testaussage mit einem Idiom wie diesem schreiben.

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) 

Dieser Ansatz nutzt die Tatsache, dass Scala match Ausdruck ergibt einen Wert.

Hier ist eine prägnantere Version, die kein Merkmal AppendedClues erfordert oder das Ergebnis des Übereinstimmungsausdrucks einer val zuweist.

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

Ich denke eigentlich, es ist schlimmer als die Lösung in der Frage: Fehler gibt eine weniger nützliche Nachricht. –

+0

Das ist ein guter Punkt. Ich habe meine Antwort verbessert, um dieses Problem anzugehen, aber diese Lösung entspricht möglicherweise nicht Ihrem Ziel, "prägnant" zu sein. –

Verwandte Themen