如何让Scalatest与Spraytestkit和HttpServiceActor配合使用

5

我查看了spray 1.3.1测试工具文档,但是没有找到适合下面需求的正确示例:

我有一个spray 1.3.1服务的样例。

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

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

我试图使用 spray test-kit 进行测试,但无法成功。这是我的 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")
    }
  }
}

然而,我遇到了以下问题:

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

和:

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

有没有解决方法? 如果我希望我的服务 扩展 HttpServiceActor 并且仍然能够使用 scalatest 和 spray testkit 进行测试,是否可以实现? 如果可以,如何实现? 我想继续扩展 HttpServiceActor,因为它使生活更轻松,代码更紧凑和可读。 但是我也想使用 scalatest 进行测试。

所以我尝试根据评论中的建议将代码更新为分割成 trait 和 service:

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")
    }
  }
}

但是我收到了以下结果:

测试开始于13:26 ... [DEBUG] [05/14/2014 13:26:25.813] [ScalaTest-run] [EventStream(akka://com-server-web-conf-MyServiceTest)] logger log1-Logging$DefaultLogger已启动 [DEBUG] [05/14/2014 13:26:25.814] [ScalaTest-run] [EventStream(akka://com-server-web-conf-MyServiceTest)] 默认 日志记录器已启动,请求未处理。 org.scalatest.exceptions.TestFailedException:请求未处理 在 spray.testkit.ScalatestInterface$class.failTest(ScalatestInterface.scala:25) at


2
如果您将代码分成仅从HttpService扩展的路由部分,并将与Actor相关的内容移动到实现Actor的具体类中,则可以使其正常工作。请参见spray-template中的操作方式:https://github.com/spray/spray-template/blob/on_spray-can_1.1/src/main/scala/com/example/MyService.scala - jrudolph
@jrudolph 更新了问题,我尝试过了,它有帮助,但我仍然遇到错误... - Jas
2
现在这是一个真正的测试失败,因为你的请求(Get())不能处理空路径的URL。如果你想要在这种情况下生成真正的失败响应(404),那么你需要使用 Get() ~> sealRoute(isAliveRoute) ~> ... - jrudolph
@jrudolph 谢谢!已回答! - Jas
@jrudolph 可以发布为答案。 - Jas
1个回答

2

我遇到了类似的问题,但有一个区别。在完整语句中,我需要向另一个演员发送消息,因此我需要使用演员功能来测试其行为。我是这样解决的:

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

在 get 请求中发送消息。
path("isalive") { get {
ctx: RequestContext => homeS.tell(ctx, myActor ) }
//on homeS actor:
def receive = {
case ctx: RequestContext =>
  ctx.complete( ... )

但是如果你的 MyService 不需要 actor 功能,那么最好像 @jrudolph 在评论中所说的那样做。

完整代码在这里:https://github.com/kastoestoramadus/simple_zookeeper.git


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接