2013-05-12 19 views
12

Sto attraversando un periodo difficile per capire come scrivere i test in Scala quando sono coinvolti i parametri impliciti.Scala test di simulazione di parametri impliciti?

Ho il seguente (versione corta) del mio codice e test:

attuazione (Scala 2.10, Spray e 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 (Usando ScalaTest e 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) 
    } 
    } 

Questa riga, verify(request).complete(result) utilizza un marshaller implicito per trasformare Result in JSON.

Posso portare un marshaller in ambito aggiungendo implicit val marshaller: Marshaller[Result] = mock[Marshaller[Result]] ma quando eseguo il test viene utilizzata un'istanza diversa di Marshaller, quindi la verifica ha esito negativo.

Anche il passaggio esplicito del simulatore Marshaller a complete non riesce.

Quindi, qualcuno può consigliare come creare un oggetto fittizio per un parametro implicito e assicurarsi che l'istanza sia quella utilizzata?

+0

Come fa il passaggio esplicito della simulazione fallita? Perché dovresti voler usare un finto marshaller in primo luogo? (Non ho usato il mockito quindi per favore scusami se quelle sono domande stupide) – jrudolph

risposta

5

Questa è una situazione perfetta per utilizzare uno Matcher da Mockito per il marshaller arg. Non dovresti aver bisogno di prendere in giro l'implicito marshaller. Tutto ciò che si vuole veramente fare è verificare che complete sia stato chiamato con un result corrispondente a quanto previsto e anche qualche istanza del marshaller. In primo luogo, se non l'avete già fatto, portare il Mockito matchers in ambito con un'importazione in questo modo:

import org.mockito.Matchers._ 

Quindi, se si voleva corrispondenza di riferimento sul risultato, si potrebbe verificare in questo modo:

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

Oppure, se si voleva uguale corrispondente sul risultato che si potrebbe fare:

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

Il trucco con matchers è che una volta che si utilizza uno per uno arg, bisogna usarli per tutti i args, ecco perché noi abbiamo t o usarne uno anche per result.

+0

Anche io ci avevo provato. Sebbene non avessi provato a usare l'uguaglianza 'same()'. Non sono sicuro del perché (ancora) il test passi quando si usa 'verify (request) .complete (same (result)) (any [classOf [Marshaller [Result]]]) ma non passa quando si usa' verify (request) .Il (eq (risultato)) (qualsiasi (classOf [Marshaller [risultato]])) '. Grazie per il tuo suggerimento, però, ha aiutato :) – C0deAttack

+0

Poiché la variabile di richiesta è essa stessa un mock, e l'equalizzatore usa il metodo equals che non è stato stubato, ottieni sempre false quindi nessuna corrispondenza. Lo stesso è un buon adattamento qui. Se la richiesta non fosse una simulazione e invece una qualche classe di caso, eq potrebbe adattarsi meglio – cmbaxter

+1

Grazie per il seguito. Ci scusiamo per non essere chiari. Usando 'eq' il test non viene nemmeno compilato. Quando uso 'eq' il messaggio di errore è" Tipo non corrispondente, previsto: Marshaller [Booleano], attuale: Marshaller [Risultato] ". Ed è un errore su 'any (classOf [Marshaller [Risultato]])'. Non sono al 100% chiaro sul motivo per cui si verifica l'errore? È piuttosto strano – C0deAttack

Problemi correlati