测试 2 个 Futures 返回的值是否相等

Testing values returned by 2 Futures are equal to each other

为了测试 Scala 的未来价值,我使用了这段代码:

  "Simple Test" should "Test Future" in {

    val futureData1: Future[Data] = MakeData()

    futureData1 map { data => { 
      assert(data.value == 2)
    }
    }
  }

这符合预期,如何测试包含在两个 Future 中的值?

例如下面测试两个Futures如何正确修改:

  "Simple Test" should "Test Future" in {

    val futureData1: Future[Data] = MakeData()
    val futureData1: Future[Data] = MakeData()

    futureData1 map { data => {
      futureData1 map { data2 => {
        assert(data.value == data2.value)
      }
      }
    }
    }
  }

阅读 https://www.scalatest.org/user_guide/async_testing ,似乎没有描述多个 Futures 测试的文档。

像这样使用 map 不太可能按照您希望的方式工作 - 映射内部的断言在未来完成之前不会得到 运行,这很可能在测试完成后发生已经完成,即使没有,来自 assert 的异常也将被包裹到一个 future 中,并且永远不会真正抛出到主线程上,所以测试总是会通过。

您似乎在使用 scalatest,因此,混入 Eventually 可能是有意义的,这样您就可以执行这些断言 属性:

    val f = doStuff()
    eventually {
      f.value shouldBe Some(Data(2))
    }

或者,如果你更喜欢 ScalaFutures 语义(混入 ScalaFutures 而不是 Eventually),你可以这样做:

    val f = doStuff()
    whenReady(f) { data => assert(data.value == 2) }

或者只是

    assert(doStuff().futureValue.value == 2) 

这也使您的问题的答案非常明显:

    assert(future1.futureValue == future2.futureValue)

如果您仍在寻找将多个期货组合在一起的方法,您可以使用 .zip(对于两个期货)或 .sequence(对于任何数字):

    whenReady(future1 zip future2) { case (d1, d2) => assert(d1 == d2) }
    whenReady(Future.sequence(List(f1, f2, f3, f4)) { case first :: rest => 
        assert(rest.forall(_ == first))