how to make scalatest work with spraytestkit and HttpServiceActor
Asked Answered
D

1

5

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

Damsel answered 14/5, 2014 at 8:13 Comment(4)
It works if you split up your code into the route part which just extends from HttpService and move the actor relevant stuff into the concrete class implementing the actor. See how it's done in the spray-template: github.com/spray/spray-template/blob/on_spray-can_1.1/src/main/…Necolenecro
@Necolenecro updated question, i tried that it helped, but i still have an error...Damsel
That's now a genuine test failure as your request (Get()) didn't handle URLs with an empty path. If you want to have actual failure responses (404) to be generated in that case you have use Get() ~> sealRoute(isAliveRoute) ~> ....Necolenecro
@Necolenecro can be posted as answer..Damsel
A
2

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

Almanza answered 14/11, 2014 at 3:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.