2012-07-29 3 views
7

Ich habe einen Specs-Test erstellt, um einige JSON-Parsing zu validieren. Obwohl der Test perfekt funktioniert, fühlt es sich ziemlich laut an.Gibt es einen Specs Matcher, der die Option Option und Entweder

Ich frage mich, ob es in den Spezifikationen vorhandenen Code gibt, um Option und Entweder?

"twitter json to Scala class mapper" should { 
    "parsing a tweet" in { 
     TwitterJsonMapper.tweetP(tweetS) match { 
     case Right(t: Tweet) => { 
      implicit def unOption[T](t: Option[T]): T = t.get 
      implicit def unEither[T](t: Either[T,Throwable]): T = t match {case Left(left) => left ;case Right(t) => throw t} 
      "test id" in { 
      true must_== (t.id.get == 228106060337135617l) 
      } 
      "test id_str" in { 
      true must_== (t.id_str.get == "228106060337135617") 
      } 
      "test time" in { 
      true must_== (t.created_at.getHours == 13) 
      } 
     } 
     case Left((pe: JsonParseException, reason: String)) => fail(reason + "\n" + pe) 
     } 
    } 
    } 

//The Tweet is produced from JSON using Fasterxml's Jackson-Scala library. 
//I want to use Option or Either monads over all child attributes - for the usual reasons. 
case class Tweet(
    @BeanProperty contributors: Option[String], 
    @BeanProperty coordinates: Option[String], 

    @BeanProperty @JsonDeserialize (
     using = classOf[TwitterDateDeserializer] 
) created_at: Either[Date,Throwable], 
    @BeanProperty favorited: Boolean = false, 
    //elided etc etc 
    @BeanProperty id_str: Option[String] 
} 
+1

Ja, die Matcher Führung sehen: http://etorreborre.github.com/specs2/guide/org.specs2.guide.Matchers.html#Matchers –

+0

Ah, ok. Ich vergaß zu sagen, ich bin immer noch in Specs 1. Ich hatte nur so viel Zeit für die Aktualisierung meiner Bibliotheken. Ist das Feature nicht in Specs 1? –

+0

Es ist einfach so schwierig, eine zuverlässige scala/maven/eclipse/specs - toolchain zu bekommen - und läuft. Ich habe Spezifikationen, um mit Eclipse zu arbeiten und diesen Teil meiner Abhängigkeiten eingefroren. –

Antwort

7

Es gibt in der Tat einige spezifische Matcher für Option und Either:

t.id must beSome(228106060337135617l) 
t.id_str must beSome("228106060337135617") 
t.created_at.left.map(_.getHours) must beLeft(13) 
+0

Übrigens, anstatt "true must _ == (t.id.get == 228106060337135617l)" zu schreiben, kann man schreiben (t.id.get == 228106060337135617l) muss "True" sein, wenn Sie einen booleschen Wert testen wollen. – Eric

+0

Ja, das ist ästhetischer –

+0

Diese Matcher sind nicht typsicher. 'Left (24) muss Left sein (" FUBAR ")' und 'Einige (42) müssenSome (" FUBAR ")' sein, die beide kompilieren. Sie schlagen nur zur Laufzeit fehl. Auf lange Sicht werden die zusätzlichen Wörter die Zeit wert sein, die Sie verschwendet haben, um herauszufinden, warum Ihr Test fehlschlägt. – drstevens

2

Ich habe dies nicht notwendig gefunden. Denken Sie daran, Option/Beide haben Wertgleichheit. Passen Sie einfach die Option/Entweder an, anstatt die Werte zu vergleichen, die sie enthalten.

 "Option should match other options" >> { 
     Some(21) must be equalTo Some(21) 
     } 

     "Either should match Either" >> { 
     Right("Some string") must be equalTo Right("Some string") 
     } 

Ich habe nicht versucht, diese zu kompilieren, aber sie sollten funktionieren. Sie müssen möglicherweise einige explizite Eingabe hinzufügen (oder must_== verwenden, die nicht sicher ist, geben)

 t.id must be equalTo Some(228106060337135617l) 
     t.id_str must be equalTo Some("228106060337135617") 
     t.created_at.left.map(_.getHours) must be equalTo Left(13) 
+0

Der Versuch, Unordnung zu reduzieren, haben 34 Attribute zu validieren –

+0

Nun, normalerweise hätte ich nicht jedes Attribut eingewickelt, das ich war versuchen zu validieren. Ich habe das nur getan, weil es in deinem Beispiel war. Ich habe aktualisiert, um die zusätzlichen Spezifikationen zu entfernen. – drstevens

Verwandte Themen