Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make scalatest work with spraytestkit and HttpServiceActor

Tags:

scala

akka

spray

I looked at spray 1.3.1 testkit documentation but could not find a proper example for what I need below: I have this sample spray 1.3.1 service

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

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

I'm trying to test it with spray test-kit but failing to do so here is my 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")
    }
  }
}

However I get

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 { ^
^

and:

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

Are there ways around this? Can I have my service extend HttpServiceActor and still be able to test it with scalatest and spray testkit? if so how? I want to continue extending HttpServiceActor makes life easier and code more compact and readable. But I would also like to test it with scalatest.

so i tried updating the code as comment said to split to trait and service as in: 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")
    }
  }
}

but i get:

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

like image 389
Jas Avatar asked Nov 01 '22 23:11

Jas


1 Answers

I had similar problem with one difference. At complete statement I had sending message to another actor, so I needed actor functionality to test behavior. I solved it that way:

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

and sending message inside get to

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

but if you don't need actor functionality of in MyService then better is to do like @jrudolph said in comment.

Full code here: https://github.com/kastoestoramadus/simple_zookeeper.git

like image 132
Waldemar Wosiński Avatar answered Nov 15 '22 06:11

Waldemar Wosiński