2013-05-12 10 views
12

Mam trochę trudny czas próbując zrozumieć, jak pisać testy w Scala, gdy zaangażowane są niejawne parametry.Testowanie Scala kpiąca z ukrytych parametrów?

Mam następujący (krótka wersja) mojego kodu i testów:

Wdrażania (Scala 2.10, Spray i 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 (używając ScalaTest i 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) 
    } 
    } 

Ta linia, verify(request).complete(result), używa domyślnego programu Marshaller, aby przekształcić Result w JSON.

Mogę przyprowadzić koordynatora do zakresu, dodając implicit val marshaller: Marshaller[Result] = mock[Marshaller[Result]], ale po uruchomieniu testu jest używane inne wystąpienie programu Marshaller, więc weryfikacja nie powiedzie się.

Nawet przekazanie fałszywego kodu Marshaller do complete nie powiedzie się.

Czy ktoś może doradzić, jak utworzyć fałszywy obiekt dla niejawnego parametru i upewnić się, że ta instancja jest używana?

+0

Jak jawnie przechodzi próba? Dlaczego miałbyś chcieć użyć symulatora marshallera? (Nie użyłem mockito, więc przepraszam, jeśli to głupie pytania) – jrudolph

Odpowiedz

5

Jest to idealna sytuacja, aby użyć Matcher z Mockito dla argumentu marshallera. Nie powinieneś wyśmiewać niejawnego koordynatora. Wszystko, co naprawdę chcesz zrobić, to sprawdzić, czy complete został wywołany z result pasujący do tego, co się spodziewałem, a także niektóre wystąpienie Marshaller. Po pierwsze, jeśli jeszcze tego nie zrobił, przynieść Mockito dopasowujące do zakresu z importu tak:

import org.mockito.Matchers._ 

Następnie, jeśli chciał dopasowanie odniesienia na wynik, można sprawdzić, jak tak:

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

Lub, jeśli chciał równa dopasowanie na wynik można zrobić:

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

sztuczka z dopasowujących jest to, że raz użyć jednego dla jednej arg, trzeba używać ich dla wszystkich args, więc dlatego mamy t o użyj też jednego dla result.

+0

Próbowałem też. Chociaż nie próbowałem używać 'same '()' matcher. Nie jestem pewien, dlaczego (jeszcze) test przechodzi przy użyciu 'verify (request) .complete (same (result)) (any [classOf [Marshaller [Result]]])', ale nie przechodzi przy użyciu 'verify (request)) .complete (eq (result)) (any (classOf [Marshaller [Result]])) ". Dzięki za twoją sugestię pomogło :) – C0deAttack

+0

Ponieważ zmienna żądania jest sama w sobie próbą, a eq matcher używa metody równości, która nie została zgaszona, zawsze otrzymujesz fałsz, więc nie pasuje. To samo pasuje tutaj. Jeśli prośba nie była udawana, a zamiast tego niektóre klasy przypadków, eq może pasować lepiej – cmbaxter

+1

Dzięki za kontynuację. Przepraszamy za brak jasności. Używając 'eq' test nawet się nie kompiluje. Kiedy używam 'eq' komunikat o błędzie to" Niezgodność typu, oczekiwane: Marshaller [Boolean], aktualny: Marshaller [Wynik] ". I jest to błąd na 'any (classOf [Marshaller [Result]])'. Nie jestem w 100% jasne, dlaczego błąd występuje? To dość dziwne. – C0deAttack

Powiązane problemy