2014-05-14 13 views
5

Spojrzałem na spray 1.3.1 testkit documentation ale nie mógł znaleźć odpowiedniego przykład za to, co muszę poniżej: mam ten próbkę spray 1.3.1 usługjak uczynić pracę scalatest z spraytestkit i HttpServiceActor

trait MyService extends HttpServiceActor { 
    def receive = runRoute(routes) 

    val isAliveRoute = path("isalive") { 
    get { 
     complete("YES") 
    } 
    } 
    val routes = isAliveRoute 
} 

próbuję go przetestować z spray test-kit ale braku zrobić tak tutaj jest mój TestCase

@RunWith(classOf[JUnitRunner]) 
class MyServiceTest extends FlatSpec with ScalatestRouteTest with ShouldMatchers with MyService { 
    "The service" should "return a greeting for GET requests to the isalive" in { 
    Get() ~> isAliveRoute ~> check { 
     responseAs[String] should be("YES") 
    } 
    } 
} 

jednak mam

Error:(15, 87) illegal inheritance; superclass FlatSpec is not a subclass of the superclass HttpServiceActor of the mixin trait MyService class MyServiceTest extends FlatSpec with ScalatestRouteTest with ShouldMatchers with MyService { ^
^

oraz:

Error:(17, 11) could not find implicit value for parameter ta: MyServiceTest.this.TildeArrow[spray.routing.RequestContext,Unit] Get() ~> isAliveRoute ~> check { ^

Czy istnieją sposoby obejścia tego? Czy mogę zlecić serwis extend HttpServiceActor i nadal można go przetestować za pomocą zestawu testów skalowalnych i spray? Jeśli tak to jak? Chcę kontynuować rozszerzanie HttpServiceActor ułatwia życie i kodu bardziej kompaktowy i czytelny. Ale chciałbym też przetestować go z największą skalą.

więc próbowałem aktualizacji kodu jako komentarz powiedział podzielić na trait i obsługa, jak w: https://github.com/spray/spray-template/blob/on_spray-can_1.1/src/main/scala/com/example/MyService.scala

class MyServiceActor extends Actor with MyService { 
    def actorRefFactory = context 
    def receive = runRoute(routes) 
} 

trait MyService extends HttpService { 

    val isAliveRoute = path("isalive") { 
    get { 
     complete("OK") 
    } 
    } 
    val routes = isAliveRoute 
} 




@RunWith(classOf[JUnitRunner]) 
class MyServiceTest extends FlatSpec with ShouldMatchers with MyService with ScalatestRouteTest { 
    def actorRefFactory = system 

    "The service" should "return a greeting for GET requests to the isalive" in { 
    Get() ~> isAliveRoute ~> check { 
     responseAs[String] should be("YES") 
    } 
    } 
} 

ale ja dostać:

Testing started at 13:26 ... [DEBUG] [05/14/2014 13:26:25.813] [ScalaTest-run] [EventStream(akka://com-server-web-conf-MyServiceTest)] logger log1-Logging$DefaultLogger started [DEBUG] [05/14/2014 13:26:25.814] [ScalaTest-run] [EventStream(akka://com-server-web-conf-MyServiceTest)] Default Loggers started Request was not handled org.scalatest.exceptions.TestFailedException: Request was not handled at spray.testkit.ScalatestInterface$class.failTest(ScalatestInterface.scala:25) at

+2

To działa, jeśli podzielić swój kod do części trasy, która właśnie rozciąga się od 'HttpService' i przenieść aktor istotnych rzeczy do konkretnej klasy wykonawczego aktora. Zobacz, jak to się robi w szablonie sprayu: https://github.com/spray/spray-template/blob/on_spray-can_1.1/src/main/scala/com/example/MyService.scala – jrudolph

+0

@jrudolph updated question , próbowałem, aby pomógł, ale nadal mam błąd ... – Jas

+2

To jest teraz prawdziwy błąd testu, ponieważ twoje żądanie ('Get()') nie obsługuje adresów URL z pustą ścieżką. Jeśli chcesz wygenerować faktyczne odpowiedzi awaryjne (404) w tym przypadku, użyj 'Get() ~> sealRoute (isAliveRoute) ~> ...'. – jrudolph

Odpowiedz

2

miałem podobny problem z jedną różnicą. Na kompletne oświadczenie wysłałem wiadomość do innego aktora, więc potrzebowałem funkcjonalności aktora do testowania zachowania. Rozwiązałem to w ten sposób:

trait MyService extends HttpService { 
val myActor: ActorRef 
val homeS: ActorRef 
(...) 

i wysyłanie wiadomości wewnątrz dostać się do

path("isalive") { get { 
ctx: RequestContext => homeS.tell(ctx, myActor) } 
//on homeS actor: 
def receive = { 
case ctx: RequestContext => 
    ctx.complete(...) 

ale jeśli nie potrzebują funkcji aktor w MyService wtedy lepiej jest zrobić jak @jrudolph powiedział w komentarzu.

Pełny kod tutaj: https://github.com/kastoestoramadus/simple_zookeeper.git