由于您不模拟“Google”,因此进行集成内部测试似乎是一种奇怪的方式,因此更像是集成外部测试和同步TestActorRef
在这里不太适合。控制喷雾内螺纹的要求也非常棘手。但是,如果您真的需要它来进行 http-request - 这是可能的。在一般情况下,您必须在您的application.conf
:
- “manager-dispatcher”(来自 Http.scala)来调度你的
IO(Http) ? req
- “host-connector-dispatcher”由
HttpHostConnector
(或ProxyHttpHostConnector
)实际调度您的请求使用它
- “设置组调度程序”为
Http.Connect
它们都在喷雾文档的配置部分中进行了描述。它们都指向“akka.actor.default-dispatcher”(请参阅 Dispatchers),因此您可以通过更改这个来更改所有这些。
这里的问题是调用线程实际上并不能保证是你的线程,所以它对你的测试没有多大帮助。想象一下,如果一些参与者注册了一些处理程序,响应您的消息:
//somewhere in spray...
case r@Request => registerHandler(() => {
...
sender ! response
})
响应可能是从另一个线程发送的,因此response.value
可能仍None
处于当前状态。实际上,响应将从底层套接字库的侦听线程发送,独立于您的测试线程。简单地说,请求可能会在一个(您的)线程中发送,但响应会在另一个线程中接收。
如果您真的需要在这里阻止,我建议您将此类代码示例(如IO(Http) ? HttpRequest
)移出并在测试中以任何方便的方式模拟它们。像这样发送:
trait AskGoogle {
def okeyGoogle = IO(Http) ? HttpRequest(GET, Uri("http://www.google.com"))).mapTo[HttpResponse]
}
trait AskGoogleMock extends AskGoogle {
def okeyGoogle = Await.result(super.okeyGoogle, timeout)
}
class Processor extends Actor with AskGoogle {
override def receive = {
case Msg(n) =>
val response = okeyGoogle
println(response.value)
}
}
val realActor = system.actorOf(Props[Processor])
val mockedActor = TestActorRef[Processor with AskGoogleMock]
顺便说一句,您可以IO(HTTP)
与另一个TestActorRef
自定义actor模拟,它将为您执行外部请求 - 如果您有一个大项目,它应该需要最少的代码更改。