2013-05-12 3 views
12

J'ai du mal à comprendre comment écrire des tests dans Scala lorsque des paramètres implicites sont impliqués.Scala teste des paramètres implicites?

Je donne les résultats suivants (version courte) de mon code et test:

mise en œuvre (Scala 2.10 Spray et Akka):

import spray.httpx.SprayJsonSupport._ 
import com.acme.ResultJsonFormat._ 

case class PerRequestIndexingActor(ctx: RequestContext) extends Actor with ActorLogging { 
    def receive = LoggingReceive { 
    case AddToIndexRequestCompleted(result) => 
     ctx.complete(result) 
     context.stop(self) 
    } 
} 


object ResultJsonFormat extends DefaultJsonProtocol { 
    implicit val resultFormat = jsonFormat2(Result) 
} 

case class Result(code: Int, message: String) 

Test (En utilisant ScalaTest et Mockito):

"Per Request Indexing Actor" should { 
    "send the HTTP Response when AddToIndexRequestCompleted message is received" in { 
     val request = mock[RequestContext] 
     val result = mock[Result] 

     val perRequestIndexingActor = TestActorRef(Props(new PerRequestIndexingActor(request))) 
     perRequestIndexingActor ! AddToIndexRequestCompleted(result) 

     verify(request).complete(result) 
    } 
    } 

Cette ligne, verify(request).complete(result) utilise un Marshaller implicite pour transformer Result en JSON.

Je peux amener un marshaller dans la portée en ajoutant implicit val marshaller: Marshaller[Result] = mock[Marshaller[Result]] mais lorsque j'exécute le test, une instance différente de Marshaller est utilisée, donc la vérification échoue.

Échec du passage explicite du faux Marshaller à complete. Donc, quelqu'un peut-il conseiller comment créer un objet fantaisie pour un paramètre implicite et s'assurer que cette instance est celle utilisée?

+0

Comment le passage explicite de la simulation échoue-t-il? Pourquoi voudriez-vous utiliser un simulateur de marshaller en premier lieu? (Je n'ai pas utilisé mockito alors s'il vous plaît excusez-moi si ce sont des questions stupides) – jrudolph

Répondre

5

Ceci est une situation idéale pour utiliser un Matcher de Mockito pour l'argument marshaller. Vous ne devriez pas avoir besoin de simuler le marshaller implicite. Tout ce que vous voulez vraiment faire est de vérifier que complete a été appelé avec un result correspondant à ce que vous attendiez et aussi une instance du marshaller. Tout d'abord, si vous ne l'avez pas déjà fait, mettre le Mockito Matchers dans le périmètre d'une importation comme ceci:

import org.mockito.Matchers._ 

Ensuite, si vous vouliez correspondant de référence sur le résultat, vous pouvez vérifier comme ceci:

verify(request).complete(same(result))(any[classOf[Marshaller[Result]]]) 

Ou, si vous voulez égal correspondant sur le résultat que vous pourriez faire:

verify(request).complete(eq(result))(any(classOf[Marshaller[Result]])) 

Le truc avec matchers est qu'une fois que vous utilisez un pour un arg, vous devez les utiliser pour tous args, c'est pourquoi nous avons t o en utiliser un pour result aussi.

+0

Je l'avais essayé aussi. Bien que je n'ai pas essayé d'utiliser le '' même() 'matcher. Je ne sais pas pourquoi (encore) le test passe en utilisant 'verify (request) .complete (same (result)) (any [classOf [Marshaller [Résultat]]])' mais ne passe pas en utilisant 'verify (request) .complete (eq (résultat)) (any (classOf [Marshaller [Résultat]])) '. Merci pour votre suggestion, cependant, il a aidé :) – C0deAttack

+0

Parce que la variable de demande est elle-même un simulacre, et l'eq matcher utilise la méthode equals qui n'a pas été stubbed, vous obtenez toujours faux ainsi aucune correspondance. La même chose est un bon ajustement ici. Si la requête n'était pas un simulacre et à la place une classe de cas, l'eq pourrait mieux convenir – cmbaxter

+1

Merci pour le suivi. Toutes mes excuses pour ne pas être clair. En utilisant 'eq' le test ne compile même pas. Quand j'utilise 'eq' le message d'erreur est" Type mismatch, expected: Marshaller [Boolean], actuel: Marshaller [Résultat] ". Et c'est une erreur sur 'any (classOf [Marshaller [Résultat]])'. Je ne suis pas 100% clair sur pourquoi l'erreur se produit? C'est plutôt étrange. – C0deAttack

Questions connexes