20

我正在使用 Spray 编写一个简单的测试规范,但我无法正确编译它,不知道我是否做错了什么。我的 scala 版本是 2.9.3 和 spray 1.0.1(更新它们中的任何一个都不是合适的选择)。这是我的测试规范的代码:

import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.http._
import akka.util.Duration
import java.util.concurrent.TimeUnit

import service.MyProxy

abstract class MyTestSpec extends Specification with Specs2RouteTest with MyProxy{

  val duration = Duration(30, TimeUnit.SECONDS)
  implicit val routeTestTimeout = RouteTestTimeout(duration)

  "MyProxy" should {

    "return a json for GET requests to the /api/getclass/classCode path for a regular request" in {
      Get("/api/getclass/123/") ~> myRoutes~> check {
        responseAs[String] must contain("classCode")
        contentType === ContentTypes.`application/json`
      }
    }

  } // end should...
} //end class

运行测试时出现此错误。

[error] C:\Users\Desktop\Project\MyTestSpec.scala:23: could not find implicit value for parameter ta: MyProxySpec.this.TildeArrow[spray.routing.RequestContext,Unit]
[error]       Get("/api/getclass/123/") ~> myRoutes~> check {
[error]                                         ^
[error] one error found
[error] (test:compile) Compilation failed

我已经尝试过在其他问题上看到的不同解决方案,但到目前为止似乎没有任何效果。

Spray.io:无法编译测试规范

如何使用 spraytestkit 和 HttpServiceActor 使 scalatest 工作

用于测试路线的基本 Spray-Testkit 用法不起作用

https://groups.google.com/forum/#!topic/spray-user/H5hkXuDGWYQ

https://groups.google.com/forum/#!topic/spray-user/zFUJSVBPM5c

注意:为了记录,我没有使用 scalatest 或 scalacheck 。纯粹是[spray]路由测试。而MyProxy扩展了Actor

4

7 回答 7

9

我只是在这个问题上苦苦挣扎。为了弄清楚这一点,我浏览了Akka HTTP 代码库,这是一个implicits 丛林。

我的问题似乎是,如果没有正确的辅助,就找不到implicit正确的实例。TildeArrow如果您查看代码,TildeArrow错误消息中所需的实例在伴随对象中定义为 animplicit def injectIntoRoute并且它需要大量其他implicits。

我建议在没有任何隐含糖的情况下写出你的代码。这应该更好地帮助编译器为您提供正确的错误消息:

"MyProxy" should {
  "return a json for GET requests to the /api/getclass/classCode path for a regular request" in {
    val request = Get("/api/getclass/123/")
    val requestWithRoutes = request.~>(myRoutes)(TildeArrow.injectIntoRoute)
    requestWithRoutes.~>(check {
      responseAs[String] must contain("classCode")
      contentType === ContentTypes.`application/json`
    })
  }
}

我认为原因是由于没有implicit可用的具体实例,编译器试图用 来满足隐式解析abstract class TildeArrow,而完全未指定的抽象type,ta.Out没有~>定义。

在我的具体情况下,我错过了一个隐含的ExecutionContextExecutor,无论这意味着什么。


更新

实际上,我进一步研究了它,问题是我implicit def ec: ExecutionContextExecutor在我的路由特征中声明了一个,但trait RouteTest将其名称定义为executor,所以当我定义自己的来满足缺失的隐式时,我最终得到了两个相同的隐式。

这是一个可爱的 API,但隐含的魔法是失控的,IMO,特别是考虑到错误消息往往是多么神秘。

于 2016-01-10T01:40:22.453 回答
4

ScalatestRouteTest 已经提供了一个隐式的 ActorySystem。从您的 actorRefFactory 方法中删除“隐式”修饰符,测试应该会被执行。

Spray.io:无法编译测试规范

于 2015-12-04T14:35:11.007 回答
3

对于akka http:

在我的情况下,它指的是akka-http-microservice

  • implicit修饰符executionContext也需要去掉
  • 并且应该像这样重新排序特征:class ServiceSpec extends FlatSpec with Matchers with Service with ScalatestRouteTest
于 2017-04-12T06:44:07.323 回答
2

就我而言,在我还导入的 TestCase 中出现了 not found 隐式错误import monix.execution.Scheduler.Implicits.global(可能有某种ExecutionContext.

我修复了它,只是在我需要的方法中添加了 monix 调度程序导入,而不是在顶部导入中。

于 2018-07-12T09:29:55.097 回答
1

如果myRoutes实际上不是路由而是Directive[HNil].

因此,我猜测在您未显示的 service.MyProxy 类中,您的路线未完成。

IE

trait MyProxy extends HttpService {
   val myRoutes = path("foo") 
}

给出这个错误

trait MyProxy extends HttpService {
  val myRoutes = path("foo") {
   complete(StatusCodes.Accepted)
 }
}

才不是。

于 2015-02-05T16:59:20.633 回答
0

您的 build.sbt 应该具有 akka-stream 测试和 akka 测试的依赖项。

那么它应该得到任何依赖项。

请参阅此文档:-

scala路由测试文档

于 2019-04-21T12:06:11.380 回答
0

为了扩展先前给出的答案,有一些隐式不应由您的 Test Class 扩展的任何其他 Trait 或类声明:

  • 演员系统
  • 执行上下文
  • DefaultHostInfo(包 akka.http.scaladsl.testkit)
  • ActorMaterializer

如果其中任何一个在 in 以外的其他地方声明ScalatestRouteTest,您将抛出以下错误:

could not find implicit value for parameter ...TildeArrow[RequestContext, SomethingHereOther]
于 2019-11-18T16:24:38.770 回答