Tag: Oleksandr Leuschenko

使用TestScheduler测试反应式代码

TL; DR 异步反应性函数,例如Observable.interval() , Observable.timer()或您自己的异步反应性函数,可以通过沿时间轴移动被测对象来使用RxTest.TestScheduler进行测试。 真正忙碌的人可能会立即深入那里的代码: vadimue / RxLocation RxLocation –反应性使用CoreLocation github.com 简单样本 我们都写测试,不是吗? 😏有时我们甚至使用TDD。 通常,我们将Observables用于多个异步操作。 但是用单元测试来测试它们可能很棘手。 如果我们不编写DispatchQueue.main.asyncAfter()或wait(for: [expectation], timeout: 60)异步测试将失败。 否则,我们可能将Rx用于同步操作,这就是为什么我们不会在执行等待时遇到问题。 例如,让我们看一个测试,该测试涵盖了当用户点击单元格时打开带有详细说明的页面。 该测试同步运行,这就是为什么它呈绿色的原因。 与时间有关的要求 有时需要描述测试中与时间相关的要求。 如果您需要测试发送API请求并同时显示UIActivityIndi​​cator怎么办? 还是基于某些延迟下载数据? 测试可能需要一段时间才能运行,因为它们必须等待操作完成。 显然,我们旨在加快运行测试的速度,因为我们经常运行测试并且不想浪费时间。 那么我们应该如何为这些情况编写测试? 我建议从业务需求入手。 假设您创建了一个用于监视用户位置的应用程序: 您可以使用CoreLocation框架; 实现CLLocationManagerDelegate并使之具有响应性(重用来自官方存储库CLLocationManager + Rx.swift和RxCLLocationManagerDelegateProxy.swift的扩展); 使用这些扩展创建单独的服务; 之后获取微小的LocationServiceProtocol的实现。 方法location()返回原始CLLocation对象序列。 在当前的实现中,它们每秒以最简单的配置到达。 那么,需求呢? 位置数据传输应该是周期性的,取决于运行和以下规则: 传输必须至少每分钟执行一次(静止),并且位置变化超过10 m; 传输的频率不应超过每10秒一次。 为了使代码简单(嗨,SRP!),我创建了单独的类,该类将过滤虚拟位置序列。 TrackingService符合该协议: 让我们从描述第一个要求开始: 传输必须每分钟至少执行一次。 要遵循TDD,我们应该首先编写测试。 为此创建并设置XCTestCase类: 时间旅行 现在我们可以编写我们的第一个测试。 这是最终版本。 […]

迅速。 功能可选。 第1部分

Optional是Swift中的基本类型。 尽管几乎无处不在,但大多数开发人员并未充分利用它,甚至没有以错误的方式使用它。 可选绑定反对DRY原理,并引入了不必要的条件。 在这个由多部分组成的系列文章中,我们将讨论Optional真正含义,如何正确使用它并应用一些高级知识,以便为Optional计算创建方便的功能性eDSL。 其他重要主题包括Swift中的依赖项注入策略,错误处理,隐式展开的Optionals和类型强制转换。 虽然不能总是避免使用最后两个,尤其是在与Objective-C代码交互时,但它们都是纯Swift的代码味道。 由于本系列的主要目的是理解功能概念以及如何在Swift中应用它们 ,因此我们将讨论和绘制而不是代码。 您会看到,还有很多工作要做。 第一部分从Optional 。 然后我们将讨论可选绑定 。 我们的旅程将把我们引向基本的功能概念: 纯功能 。 在那里,我们将停下来,探索更多内容,直到下一部分。 为什么可选? 在Objective-C中没有“ Optional这样的类型。 相反,如果函数或属性不返回值,则返回nil 空的 NSObject指针。 可以安全地将消息发送到nil并将其作为参数传递。 但是Swift没有像Objective-C这样的指针。 此外,如果任何类型可以为nil ,我们的程序如何保证类型安全? 如果我们传递nil字符串而不是数字,编译器如何弄清楚怎么办? 如果我们将nil传递给无法处理的函数怎么办? 为了处理此问题,引入了Optional 。 有什么可选的? 让我们看一下Optional声明: 枚举可选 { ///没有值 无案 ///值的存在 案例一些(包装) … } 因此,我们看到的第一件事告诉我们Optional是容器类型 :它封装了一个值。 图片 1.简单显示一个可选的Int值容器。 这里的黄色圆圈表示普通类型,而蓝色正方形表示“可选”容器。 您会看到, .none没有任何类型约束,因此使用诸如nil这样的文字很方便。 一个空盒子只是一个盒子,没有什么有趣的。 Optional还可以保护您避免将nil值传递给无法处理它们的函数。 这就是可选绑定起作用的地方。 可选绑定 可选绑定是用于访问包装到Optional的值的语句。 它看起来比声音更好,并且具有熟悉的语法。 如果您已经尝试过一些Swift,您将不会感到害怕 […]