使用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并测试以下内容:
- 状态更新:在执行操作以验证Reactor逻辑时检查每个状态变量的更新。
- 执行次数:确保对网络请求和其他函数调用进行了正确的次数。
- 确保状态发出正确的次数。
初始设置
我将以下文件夹结构用于测试:
存根存储库:存储库是公开公共方法的结构,您可以使用这些方法通过网络请求获取数据。 存根存储库文件夹包含使用存根创建的模拟存储库。
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上找到。 随时分享反馈或在评论中提出问题。 🙂