如果我需要通过spray-can编写涉及HTTP请求的集成测试,我该如何确保spray-can正在使用CallingThreadDispatcher?
目前,以下演员将打印None
class Processor extends Actor {
override def receive = {
case Msg(n) =>
val response = (IO(Http) ? HttpRequest(GET, Uri("http://www.google.com"))).mapTo[HttpResponse]
println(response.value)
}
}
如何确保在与测试相同的线程上执行请求(导致同步请求)?
答案 0 :(得分:1)
进行集成内部测试似乎很奇怪,因为你不会嘲笑" Google"所以更像是集成外部测试和同步TestActorRef
没有&#39非常适合这里。控制喷涂内螺纹的要求也相当棘手。但是,如果您确实需要http请求 - 它是可能的。一般情况下,您必须在application.conf
:
IO(Http) ? req
HttpHostConnector
(或ProxyHttpHostConnector
)使用它Http.Connect
所有这些都在Configuration Section喷雾文件中描述。他们都指向" akka.actor.default-dispatcher" (参见Dispatchers),因此您可以通过更改此更改来更改所有这些内容。
这里的问题是调用线程实际上并不保证你的线程,所以它对你的测试没有多大帮助。试想一下,如果一些演员注册了一些处理程序,请回复你的消息:
//somewhere in spray...
case r@Request => registerHandler(() => {
...
sender ! response
})
响应可能是从另一个线程发送的,因此response.value
当前可能仍为None
。实际上,响应将从底层套接字库的监听线程发送,独立于测试的线程。简单地说,请求可以在一个(您的)线程中发送,但响应在另一个线程中发送。
如果你真的需要在这里阻止,我会建议你移动这些代码样本(如IO(Http) ? HttpRequest
)并在测试中以任何方便的方式模拟它们。这样的Smtng:
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,它会为您执行外部请求 - 如果您有一个大项目,则应该需要最少的代码更改。< / p>