【问题标题】:What is the best way to assert for a scala method whose return type is Future[Unit]断言返回类型为 Future[Unit] 的 scala 方法的最佳方法是什么
【发布时间】:2018-12-15 01:01:23
【问题描述】:

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

def 计算(x: Int, y: Int): Future[Unit] = { ........... }

现在我需要测试这个方法。验证Future.successful(()) case 的测试的最佳断言方法是什么。

【问题讨论】:

  • 你在使用框架测试吗?你试过了吗?
  • 我正在使用 scalatest。

标签: scala future assert scalatest


【解决方案1】:

Scalatest 提供了几种使用 Futures 的方法。

选项 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% 的时间。小心!

【讨论】:

  • 我没有返回值。它的类型是 Future[Unit]
  • 那么isReadyWithin 就可以满足你的需求了。
【解决方案2】:

至少有两个选项:

  • 您可以Await.result,然后通过断言某些内容来确保结果符合您的预期。
  • 您可以在未来本身内进行断言,然后使用 AsyncFlatSpec 之类的东西进行测试。

【讨论】:

    【解决方案3】:

    我假设您已经在测试类中扩展了ScalaFutures,并且您已经根据需要配置了超时(patienceConfig)。如果您已经这样做了,那么您可以使用以下方法之一:

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

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

    第一种方法更可取,因为Unit 不能有任何其他值,因此我们不必显式检查它,除非代码出于某种原因返回null

    【讨论】:

      猜你喜欢
      • 2023-03-06
      • 2022-01-17
      • 1970-01-01
      • 2012-04-28
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      相关资源
      最近更新 更多