2012-07-29 12 views
7

He creado una prueba de especificaciones, para validar algunos análisis JSON. Aunque la prueba funciona perfectamente bien, se siente bastante ruidosa.¿Hay un comparador de especificaciones que una opción de caja y O

Me pregunto si existe un código en Especificaciones para la opción de caja y ¿O bien?

"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

Sí, ver la guía de comparadores: http://etorreborre.github.com/specs2/guide/org.specs2.guide.Matchers.html#Matchers –

+0

Ah, vale. Olvidé decir que todavía estoy en las especificaciones 1. Solo tengo tanto tiempo para actualizar mis bibliotecas. ¿La función no está en las especificaciones 1? –

+0

Es tan difícil obtener un scala/maven/eclipse/specs confiable - toolchain - en funcionamiento. Obtuve especificaciones para trabajar con Eclipse y congelé esa sección de mis dependencias. –

Respuesta

7

De hecho, existen algunos comparadores específicos para Option y Either:

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

Por cierto, en lugar de escribir 'true must _ == (t.id.get == 228106060337135617l)' puedes escribir '(t.id.get == 228106060337135617l) must beTrue' cuando quieras probar un valor booleano. – Eric

+0

Sí, eso es más estético –

+0

Estos matchers no son seguros. 'Left (24) must beLeft (" FUBAR ")' y 'Some (42) must beome (" FUBAR ")' ambos compilan. Solo fallan en tiempo de ejecución. A la larga, el par de palabras adicionales valdrá la pena el tiempo que desperdiciaste tratando de descubrir por qué tu prueba está fallando. – drstevens

2

No he encontrado esto necesario. Recuerde, Opción/O tiene valor de igualdad. Simplemente haga coincidir la Opción/O bien, en lugar de hacer coincidir los valores que contienen.

 "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") 
     } 

No intenté compilar estos, pero deberían funcionar. Puede que tenga que añadir un poco de tipificación explícita (o usa must_== que no es un tipo seguro)

 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

Tratando de reducir el desorden, tengo 34 atributos para validar –

+0

Bueno, normalmente no habría envuelto cada atributo que era tratando de validar Solo lo hice porque fue en tu ejemplo. Actualicé para eliminar el desorden de especificaciones adicionales. – drstevens

Cuestiones relacionadas