Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala未来的单元测试失败_Scala_Unit Testing_Future - Fatal编程技术网

Scala未来的单元测试失败

Scala未来的单元测试失败,scala,unit-testing,future,Scala,Unit Testing,Future,我正在尝试在我正在编写的脚本中测试错误处理。如果异步函数fetchBar失败,我将匹配失败案例,然后返回包含失败结果的成功未来 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(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函数来创建一个失败的尝试?

我认为您有点混淆了概念,但这不是100%的错误

问题是,
Future
在Scala中是一个有点不正交的概念——也就是说,它不仅代表延迟执行的概念,而且代表失败的概念

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

换句话说,以下组合有点奇怪,但仍有其用途:

  • 试试[Future[\u]]
    -Future已经捕获了故障。但是,如果您有一个(行为不好的)库方法,该方法通常返回未来,但可能会抛出“同步”路径,则该方法是有意义的:
  • 。。。但这基本上是一种解决方法,用于修复实现不佳的函数

  • Future[Try[\u]]
    -有时用于将“业务”错误(表示为
    Future.success(…)
    )与“基础架构”故障(表示为
    Future.failed(…)
    )分开。另一方面,这对akka流特别有用,因为akka流倾向于将失败的未来视为流的“致命”因素
  • 在你的情况下,你想做的是断言未来的结果。要做到这一点,实际上你至少有两个选择

  • 阻止,直到将来完成并检查结果-这通常通过
    scala.concurrent.Await来完成:
  • 使用一些支持使用futures的测试框架-例如scalatest:

  • 我认为你有点混淆了概念,但这不是你100%的错

    问题是,
    Future
    在Scala中是一个有点不正交的概念——也就是说,它不仅代表延迟执行的概念,而且代表失败的概念

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

    换句话说,以下组合有点奇怪,但仍有其用途:

  • 试试[Future[\u]]
    -Future已经捕获了故障。但是,如果您有一个(行为不好的)库方法,该方法通常返回未来,但可能会抛出“同步”路径,则该方法是有意义的:
  • 。。。但这基本上是一种解决方法,用于修复实现不佳的函数

  • Future[Try[\u]]
    -有时用于将“业务”错误(表示为
    Future.success(…)
    )与“基础架构”故障(表示为
    Future.failed(…)
    )分开。另一方面,这对akka流特别有用,因为akka流倾向于将失败的未来视为流的“致命”因素
  • 在你的情况下,你想做的是断言未来的结果。要做到这一点,实际上你至少有两个选择

  • 阻止,直到将来完成并检查结果-这通常通过
    scala.concurrent.Await来完成:
  • 使用一些支持使用futures的测试框架-例如scalatest:

  • 一个
    Try[Future[T]
    没有多大意义,特别是因为未来已经捕捉到了失败。我建议你看一下文档。
    试试[Future[T]
    没有多大意义,特别是因为Future已经捕捉到了失败。我建议您查看一下文档。
    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(...))
    
    // 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) => ???; }
    
    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
       }
    }