我的一些代码是异步的,我想测试这个代码的执行导致了正确的状态。我没有提及可以映射的Future或JS Promise的参考 - 所讨论的异步代码存在于我正在使用的JS库中,它只是调用setTimeout(setSomeState, 0)
,这就是为什么我唯一的追求是测试该状态在短暂延迟(10毫秒)后异步。如何编写异步Scala.js测试(例如使用ScalaTest)?
这是我最好的尝试:
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,但通过上面的链接之一的评论来看,似乎uTest有一个类似的问题,除了它倾向于忽略测试而不是拖延测试套件。
我只是想在短暂的延迟后作出断言,似乎应该是绝对有可能的。任何有关如何实现这一目标的建议都将非常感激。
对不起,我不明白我怎么可以把这个给我的处境。我在JS库里面调用了一个'baz'方法,里面有这个JS代码:'setTimeout(setSomeState,0)'。我需要声明'setSomeState'已经对我在测试范围内的变量进行了必要的修改。在我上面的例子中,我把它抽象为'assert(true)'。但是这个断言显然需要在* setSomeState运行之后发生,因此断言必须是异步的。 – Nikita
嗯,这更像是一个通用的想法......当它不适用时,我可以删除答案。 – GhostCat