使用 FakeRequests 和分块响应(Enumerator)进行 Play2 测试时是否存在错误?
Is there a bug in Play2 testing with FakeRequests and chunked responses (Enumerator)?
我 运行 在测试 returns 使用枚举器的分块响应的 Action 时遇到 Play 2.3.7 的问题:
def text = Action {
Ok.chunked(Enumerator("abc"))
}
使用 curl http://localhost:9000/text
我得到了预期的结果:abc
但以下测试:
class ApplicationSpec extends Specification {
"Application" should {
"stream text" in new WithApplication{
val request = route(FakeRequest(GET, "/text")).get
contentAsString(request) mustEqual "abc"
}
}
}
因比较错误而失败:
[info] Application should
[info] x stream text
[error] '3
[error] abc
[error] 0
[error]
[error] ' is not equal to 'abc' (ApplicationSpec.scala:31)
这些多余的字符是从哪里来的?我怀疑这可能是 FakeRequest 和 Enumerators 的问题?在操作中连接枚举器的更复杂情况下,枚举器生成的内容之间将混合字符。
这是一个已知问题,已为即将推出的 Play 2.4 修复,但在 2.3.x 中不可用。额外的字符是从分块编码中引入的。它们以十六进制表示位于每个 HTTP 响应正文开头的块长度。旧的游戏测试助手只是将它们连接在一起,而不是将它们剔除。
我一直在使用以下代码来解决 2.3.x 上的问题(感谢 marcuslinke 的 post 来自这个 github issue):
import scala.concurrent._
import scala.concurrent.duration._
import play.api.mvc._
import play.api.libs.iteratee._
import akka.util.Timeout
def contentAsBytes(of: Future[Result])(implicit timeout: Timeout): Array[Byte] = {
val result = Await.result(of, timeout.duration)
val eBytes = result.header.headers.get(TRANSFER_ENCODING) match {
case Some("chunked") => result.body &> Results.dechunk
case _ => result.body
}
Await.result(eBytes |>>> Iteratee.consume[Array[Byte]](), timeout.duration)
}
我在这样的测试 (specs2) 中使用:
new String(contentAsBytes(result)) must equalTo("expected value")
作为参考,这里是合并到 master 中的 pull request。
我 运行 在测试 returns 使用枚举器的分块响应的 Action 时遇到 Play 2.3.7 的问题:
def text = Action {
Ok.chunked(Enumerator("abc"))
}
使用 curl http://localhost:9000/text
我得到了预期的结果:abc
但以下测试:
class ApplicationSpec extends Specification {
"Application" should {
"stream text" in new WithApplication{
val request = route(FakeRequest(GET, "/text")).get
contentAsString(request) mustEqual "abc"
}
}
}
因比较错误而失败:
[info] Application should
[info] x stream text
[error] '3
[error] abc
[error] 0
[error]
[error] ' is not equal to 'abc' (ApplicationSpec.scala:31)
这些多余的字符是从哪里来的?我怀疑这可能是 FakeRequest 和 Enumerators 的问题?在操作中连接枚举器的更复杂情况下,枚举器生成的内容之间将混合字符。
这是一个已知问题,已为即将推出的 Play 2.4 修复,但在 2.3.x 中不可用。额外的字符是从分块编码中引入的。它们以十六进制表示位于每个 HTTP 响应正文开头的块长度。旧的游戏测试助手只是将它们连接在一起,而不是将它们剔除。
我一直在使用以下代码来解决 2.3.x 上的问题(感谢 marcuslinke 的 post 来自这个 github issue):
import scala.concurrent._
import scala.concurrent.duration._
import play.api.mvc._
import play.api.libs.iteratee._
import akka.util.Timeout
def contentAsBytes(of: Future[Result])(implicit timeout: Timeout): Array[Byte] = {
val result = Await.result(of, timeout.duration)
val eBytes = result.header.headers.get(TRANSFER_ENCODING) match {
case Some("chunked") => result.body &> Results.dechunk
case _ => result.body
}
Await.result(eBytes |>>> Iteratee.consume[Array[Byte]](), timeout.duration)
}
我在这样的测试 (specs2) 中使用:
new String(contentAsBytes(result)) must equalTo("expected value")
作为参考,这里是合并到 master 中的 pull request。