如何在测试规范中修复参数ta:TildeArrow的缺失隐式值

mar*_*ejo 17 routing scala scala-2.9 spray spray-test

我正在使用一个简单的测试规范使用喷雾,我无法正确编译,不知道我做错了什么.我的scala版本是2.9.3并且喷涂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
Run Code Online (Sandbox Code Playgroud)

我在运行测试时遇到此错误.

[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
Run Code Online (Sandbox Code Playgroud)

我尝试过在另一个问题上看到的不同解决方案,到目前为止似乎没有任何工作.

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.纯粹是一种[喷雾]路线测试.而MyProxy则扩展了Actor

acj*_*jay 8

我只是在努力解决这个问题.为了解决这个问题,我浏览了Akka HTTP代码库,这是implicits 的丛林.

我的问题似乎是没有正确的二级implicit到位,TildeArrow没有找到正确的实例.如果查看代码,TildeArrow错误消息中所需的实例将被定义为implicit 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`
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

我想原因是因为有对没有具体实例implicit可用时,编译器试图满足与隐含的分辨率abstract class TildeArrow,并且完全未指定的抽象type,ta.Out不具有一个~>定义.

在我的具体情况下,我错过了隐含的ExecutionContextExecutor,无论那意味着什么.


UPDATE

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

这是一个可爱的API,但隐含的魔法是失控的,IMO,特别是考虑到错误信息的含义.


hen*_*nry 1

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

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

IE

trait MyProxy extends HttpService {
   val myRoutes = path("foo") 
}
Run Code Online (Sandbox Code Playgroud)

给出这个错误

trait MyProxy extends HttpService {
  val myRoutes = path("foo") {
   complete(StatusCodes.Accepted)
 }
}
Run Code Online (Sandbox Code Playgroud)

才不是。