Scala中来自期货的单元测试失败

问题描述 投票:0回答:1

我正在尝试在编写的脚本中测试错误处理。如果异步函数fetchBar失败,则我将模式匹配失败情况,然后返回包含失败结果的成功Future。

val fetchedBar = Try(fooClient.fetchBar(params))

fetchedBar match {
  case Success(bar) => foobar(bar)
  case Failure(e) => Future.successful(FooResult(success = false))
}

但是,当我对该流进行单元测试时,我在测试失败案例时遇到了麻烦。我已将fetchBar存根以返回失败的将来,如下所示。

val fetchedBar = Try(Future.failed(new Exception()))

但是我注意到fetchedBar返回的是成功而不是失败。为什么会这样,如何将fetchBar函数存根以创建失败的Try?]

scala unit-testing future
1个回答
1
投票

我认为您是在混用一些概念,但这不是100%的错。

事实是,Scala中的Future有点非正交的概念,它不仅代表延迟执行的概念,而且代表失败的概念。

因此,在大多数情况下,将Future包装到Try中是没有多大意义的,反之亦然-除非人们想将失败的概念与异步的概念明确地分开。

换句话说,以下组合有点奇怪,但是仍然可以使用:

  1. Try[Future[_]]-将来已经捕获了故障。但是,如果您有一个(行为不佳的)库方法,该方法通常会返回Future,但可能会抛出“同步”路径,这是有道理的:
  2. def futureReciprocal(i: Int): Float = { 
       val reciprocal = 1 / i // Division by zero is intentional
       Future.successful(reciprocal)
    }
    
    futureReciprocal(0) // throws
    Try(futureReciprocal(0)) // Failure(DivisionByZero(...))
    

...但是,这基本上是解决实施不良的功能的解决方法

  1. Future[Try[_]]-有时对于将“业务”错误(由Future.success(Failure(...))表示)与“基础结构”故障(由Future.failed(...)表示)有用。一方面-这对于akka流特别有用,它会将失败的期货视为对流“致命”。

    对于您来说,您想要做的是在将来的[[结果

  2. 中断言。为此,实际上您至少有两个选择。
    阻塞直到将来完成并检查结果-通常使用scala.concurrent.Await
  • // writing this without the compiler, might mix up namespaces a bit import scala.concurrent.Await import scala.concurrent.duration.DurationInt val future = fooClient.fetchBar(...) val futureResult: Try[_] = Await.result(future, 1.second) futureResult match { case Success(_) => ??? ; case Failure(exc) => ???; }
    1. [使用一些支持使用期货的测试框架-例如最恐怖:
  • class YourTest extends FlatSpec with ScalaFutures { "fetchBar should return failed future" in { val future: Future[XYZ] = fooClient.fetchBar(...) // whenReady comes from the ScalaFutures trait whenReady(future) { result => result shouldBe XYZ } // asserting on the successful future result whenReady(future.failed) { exc => exc shoulBe a[RuntimeException] } // asserting on an exception in the failed future } }
  • © www.soinside.com 2019 - 2024. All rights reserved.