什么是断言一阶方法,其返回类型为未来[单位]的最佳方式(What is the best way t

2019-10-30 05:04发布

我有一个方法。 这种方法可能会返回Future.failed(.....)或Future.successful(())。

DEF计算(X为:int,Y:智力):未来[单位] = {} ........

现在,我需要测试这种方法。 什么是断言的验证了该测试的最好办法Future.successful(())的情况下。

Answer 1:

Scalatest提供有工作的一些方法Future秒。

选项1: isReadyWithin

import org.scalatest.concurrent.ScalaFutures._
import scala.concurrent.duration._

calculate(1, 3).isReadyWithin(1.second) should be(true)

如果你想做一些与一些返回值在这里,你可以使用whenReady

implicit val patienceConfig = PatienceConfig(1.second)

def calculateWithResult(i: Int, j: Int): Future[Int] = ???

whenReady(calculateWithResult(1,3)) { result =>
    result should be(4)
}

你需要一个隐含的PatienceConfig范围,告诉whenReady时失败,因为超时的考验。 我相信有一个默认的一个scalatest库,但选择的时间段是非常短- 10毫秒量级上的东西-而且常可引起片状测试。

选项2: AsyncXSpec

Async品种的FlatSpecFreeSpecFunSpec等特点。 他们的工作就像他们同步的品种除了任何测试,现在必须返回类型的值Future[Assertion] 。 例如:

class Test extends AsyncFreeSpec {
  "An asynchronous method" - {
    "should succeed" in {
      calculate(1,3).map { _ =>
        // just want to make sure the future completes
        succeed
      }
    }
  }
}

同样,你可以在这里对运行结果的测试。 请注意,这个变体意味着,在您的测试类的每个测试必须返回一个Future ,所以如果你想组合同步和异步测试中,它是不是很大。 我也真的不知道怎么AsyncXSpec选择它的超时值。

选项不要: Await.result

我会建议不要使用Await.result因为它会阻止线程的时间。 据我所知,上述两个方案被设计成异步测试可以并行轻松运行。

注意事项:

你想这样做异步测试的时候是超级小心你的超时。 太长了,你的测试可以结束了挂的年龄,如果出现错误。 太短暂了,你的测试将是片状。 该程序可以在不同的环境进行不同的,所以你可能会发现,超时这是你的本地计算机上完全足够了构建服务器发生故障时5%的测试。 小心!



Answer 2:

至少有两个选项:

  • 您可以Await.result ,然后确保结果是你被断言一些事情所期望的。
  • 你可以让你的断言未来自身内部,但后来使用像AsyncFlatSpec为你的测试。


Answer 3:

我假设你已经扩展ScalaFutures在测试类和已配置的超时( patienceConfig )按您的需求。 如果你这样做,那么你可以使用下面的方法之一:

whenReady(calculate(1,3))(_ => succeed)

要么

whenReady(calculate(1,3))(_ shouldBe ())

第一种方法是优选的,不能有任何其他价值Unit ,所以我们没有显式地检查它,除非代码返回null出于某种原因。



文章来源: What is the best way to assert for a scala method whose return type is Future[Unit]