使用Future时如何编写单元测试?

时间:2017-05-05 12:00:07

标签: scala unit-testing future

我编写了一个带有一些函数的类,它们执行HTTP调用并返回Future[String]。我在一个需要编写一些测试的方法中使用这些函数:

def score(rawEvent: Json) = {
  httpService
    .get("name", formatJsonAttribute(rawEvent.name))
    .onComplete { op =>
      op.map { json =>
        //What must be tested
      }
    }
}  

函数onComplete没有返回类型 - 它返回Unit。如何替换onComplete以使我的函数返回要测试的东西?

2 个答案:

答案 0 :(得分:4)

我完全同意@Michal,您应该始终使用maponCompleteFuture。但是我想指出,正如你自己所说,你想要测试的不是HTTP调用本身(它依赖于你可能不需要测试的HTTP客户端,来自你所在的服务器的响应)可能没有控制权,...),但你用它的答案做了什么。

那么为什么不编写测试,而不是编写函数score,而是编写您在onComplete(或map中编写的函数,如果您决定更改它)?< / p>

通过这种方式,您可以使用json的精确值来测试它,您可能希望将其定义为从服务器获得的结果,但您可以完全控制(例如,您可以在不强制服务器提供异常响应的情况下测试边界情况。)

测试两者(HTTP调用和回调函数)是否合在一起不是单元测试问题,而是集成测试问题,并且只有在您知道函数执行了预期的操作时才应该执行。

那时,您实际上需要检查Future的值,在这种情况下,您可以使用Await.result作为@Michal建议,或使用您的测试框架给出的相关结构。例如,scalatest对此类问题具有AsyncTestSuite特征。

答案 1 :(得分:3)

使用map代替onComplete。它还将为您提供映射函数内的解析值。 score函数的返回类型为Future[T],其中T将是您处理的结果类型。 在测试中,您可以使用scala.concurrent.Await.result()函数。