使用ReactorKit,Quick&Nimble,RxBlocking,Swift 4.1在iOS中进行单元测试

入门

我们将使用RxBlocking来验证Reactor(ViewModel)的状态。 我们还将使用Stubber 模拟我们的网络请求。 最后,您的Podfile应该包含以下内容:

  def development_pods 
吊舱“ ReactorKit”
吊舱“ RxSwift”
豆荚“ RxCocoa”
结束
  def testing_pods 
pod'RxBlocking'
吊舱“ Stubber”
豆荚“快速”
Pod'Nimble'
结束

简单的测试流程

一个简单的流程可能涉及将一个Action发送到您的Reactor并测试以下内容:

  1. 状态更新:在执行操作以验证Reactor逻辑时检查每个状态变量的更新。
  2. 执行次数:确保对网络请求和其他函数调用进行了正确的次数。
  3. 确保状态发出正确的次数。

初始设置

我将以下文件夹结构用于测试:

存根存储库:存储库是公开公共方法的结构,您可以使用这些方法通过网络请求获取数据。 存根存储库文件夹包含使用存根创建的模拟存储库

ReactorTests:包含ViewModel / Reactor测试。

存根

使用Stubber模拟您的网络请求非常容易。

您还可以通过使用以下命令来验证存根方法的执行计数

  Stubber.executions(signIn).count 

单元测试

为了测试Reactor内部的逻辑,我们需要将Reactor视为黑匣子。 我将提供一个动作作为输入,并获得UI状态作为输出。

下面,我使用一些无效参数触发signIn操作,理想情况下,在Reactor中以同步方式进行验证后,理想情况下应该发出error状态。 我将使用RxBlocking阻止代码流,直到可观察到的state发出一个事件为止。

注意使用.delay()运算符。 没有它,在执行第7行的阻塞语句之前,可能会丢失一些事件。

订阅流后, state会发出一个事件,通常是应该跳过的先前状态。 skip(1)可以帮助您。

使用take(1)完成一次发射后的流。 否则,RxBlocking将永远不允许语句失败。

如果状态在5秒钟内未发出,则RxTimeoutException会引发RxTimeoutException,并且测试用例会自动失败。

提取状态后, Nimble用于验证状态变量的值是否符合期望。

在所有期望都得到验证后,流将立即处理掉。

如果有多个国家排放怎么办?

好吧,如果有多个发射,那么我们可以使用toArray()运算符,而不是在RxBlocking中使用first()运算符。 toArray()将为您提供按以下顺序发出的状态数组。

然后,您可以使用expect逐一验证状态变量。

有什么问题吗

完整的项目可在Github上找到。 随时分享反馈或在评论中提出问题。 🙂

Interesting Posts