【发布时间】:2017-07-20 12:57:59
【问题描述】:
我的一些代码是异步的,我想测试这段代码的执行是否导致了正确的状态。我没有可以映射的 Future 或 JS Promise 的引用——有问题的异步代码位于我正在使用的 JS 库中,它只是调用setTimeout(setSomeState, 0),这就是为什么我唯一的办法是在短暂的延迟(10 毫秒)之后异步测试状态。
这是我最好的尝试:
import org.scalatest.{Assertion, AsyncFunSpec, Matchers}
import scala.concurrent.Promise
import scala.scalajs.js
import scala.scalajs.concurrent.JSExecutionContext
class FooSpec extends AsyncFunSpec with Matchers {
implicit override def executionContext = JSExecutionContext.queue
it("async works") {
val promise = Promise[Assertion]()
js.timers.setTimeout(10) {
promise.success {
println("FOO")
assert(true)
}
}
promise.future
}
}
这在断言成功时有效——使用assert(true)。但是,当断言失败时(例如,如果您将其替换为 assert(false)),测试套件会冻结。 sbt 只是停止打印任何东西,并无限期地挂起,测试套件永远不会完成。如果出现此类故障,FooSpec: 行会打印出来,但不会打印测试名称 ("async works"),也不会打印 "FOO" 字符串。
如果我注释掉 executionContext 行,我会得到“队列为空,而未来未完成,这意味着您可能为您的任务使用了错误的 ExecutionContext,请仔细检查您的未来。”以下链接之一详细解释了错误。
我认为这些链接与这个问题有关:
https://github.com/scalatest/scalatest/issues/910
https://github.com/scalatest/scalatest/issues/1039
但我想不出可行的解决方案。
我应该以不同的方式构建Future[Assertion] 吗?
我与 ScalaTest 无关,但从上面其中一个链接中的 cmets 判断,uTest 似乎也有类似的问题,只是它倾向于忽略测试而不是停止测试套件。
我只是想在短暂的延迟后做出断言,似乎这绝对是可能的。任何关于如何实现这一点的建议将不胜感激。
【问题讨论】:
标签: scala unit-testing asynchronous scalatest scala.js