Swift Combine 使用从 PassthroughSubject 预定好的发送的事件测试订阅者 从入门到精通二十三

本文主要是介绍Swift Combine 使用从 PassthroughSubject 预定好的发送的事件测试订阅者 从入门到精通二十三,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Combine 系列

  1. Swift Combine 从入门到精通一
  2. Swift Combine 发布者订阅者操作者 从入门到精通二
  3. Swift Combine 管道 从入门到精通三
  4. Swift Combine 发布者publisher的生命周期 从入门到精通四
  5. Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五
  6. Swift Combine 订阅者Subscriber的生命周期 从入门到精通六
  7. Swift 使用 Combine 进行开发 从入门到精通七
  8. Swift 使用 Combine 管道和线程进行开发 从入门到精通八
  9. Swift Combine 使用 sink, assign 创建一个订阅者 从入门到精通九
  10. Swift Combine 使用 dataTaskPublisher 发起网络请求 从入门到精通十
  11. Swift Combine 用 Future 来封装异步请求 从入门到精通十一
  12. Swift Combine 有序的异步操作 从入门到精通十二
  13. Swift Combine 使用 flatMap 和 catch错误处理 从入门到精通十三
  14. Swift Combine 网络受限时从备用 URL 请求数据 从入门到精通十四
  15. Swift Combine 通过用户输入更新声明式 UI 从入门到精通十五
  16. Swift Combine 级联多个 UI 更新,包括网络请求 从入门到精通十六
  17. Swift Combine 合并多个管道以更新 UI 元素 从入门到精通十七
  18. Swift Combine 通过包装基于 delegate 的 API 创建重复发布者 从入门到精通十八
  19. Swift Combine 响应NotificationCenter 的更新 从入门到精通十九
  20. Swift Combine 使用 ObservableObject 与 SwiftUI 模型作为发布源 从入门到精通二十
  21. Swift Combine 使用 XCTestExpectation 测试发布者 从入门到精通二十一
  22. Swift Combine 使用 PassthroughSubject 测试订阅者 从入门到精通二十二
    在这里插入图片描述

1. 使用从 PassthroughSubject 预定好的发送的事件测试订阅者

目的:当你想要测试的是管道的时序时,用于测试管道或订阅者。

在 Combine 中有许多针对数据时序的操作符,包括 debouncethrottle 以及 delay。 在进行 UI 测试之外,你可能需要测试你的管道时序具有所需的效果。

实现这个的方法之一是利用 XCTestExpectationpassthroughSubject,将两者结合起来。 基于 使用 XCTestExpectation 测试发布者 和 使用 PassthroughSubject 测试订阅者,在测试中添加 DispatchQueue,以安排 PassthroughSubject.send() 方法的调用。

一个这种用法的例子:

UsingCombineTests/PublisherTests.swift - testKVOPublisher

func testKVOPublisher() {let expectation = XCTestExpectation(description: self.debugDescription)let foo = KVOAbleNSObject()let q = DispatchQueue(label: self.debugDescription)   // 1let _ = foo.publisher(for: \.intValue).print().sink { someValue inprint("value of intValue updated to: >>\(someValue)<<")}q.asyncAfter(deadline: .now() + 0.5, execute: {  // 2print("Updating to foo.intValue on background queue")foo.intValue = 5expectation.fulfill()  // 3})wait(for: [expectation], timeout: 5.0)  // 4
}
  1. 这将为你的测试添加 DispatchQueue,并以测试的描述 debugDescription 来命名该队列。 这只在调试中测试失败时显示,并且在还有其它后台线程也在使用时,方便地提醒测试代码中发生了什么情况。
  2. .asyncAfter 和参数 deadline 一起使用,用来定义何时发起请求.
  3. 这是将任何相关的断言嵌入到订阅者或其周围的最简单的方式。此外,将 .fulfill() 作为你发送队列的最后一个条目,好让测试知道它现在已完成。
  4. 请确保当你设置等待超时时间时,有足够的时间让你的队列被调用。

此技术的一个明显缺点是,它使得测试花费的最短时间至少是测试中的最大的队列延迟。

另一种选择是第三方库,名为 EntwineTest,开发灵感来自 RxTest 库。 EntwineTestEntwine 的一部分,一个提供了一些 helpers 扩展了 Combine 的 Swift 库。 该库可以在 github 上找到,位于 https://github.com/tcldr/Entwine.git,只要使用时遵守 MIT 证书即可。

EntwineTest 中包含的关键元素之一是虚拟时间调度器,以及使用此调度器时安排(TestablePublisher)并收集和记录(TestableSubscriber)结果时间的其他类。

来自 EntwineTest 工程的 README 中的一个例子包含在:

UsingCombineTests/EntwineTestExampleTests.swift - testExampleUsingVirtualTimeScheduler

func testExampleUsingVirtualTimeScheduler() {let scheduler = TestScheduler(initialClock: 0)  // 1var didSink = falselet cancellable = Just(1)  // 2.delay(for: 1, scheduler: scheduler).sink { _ indidSink = true}XCTAssertNotNil(cancellable)// where a real scheduler would have triggered when .sink() was invoked// the virtual time scheduler requires resume() to commence and runs to// completion.scheduler.resume()  // 3XCTAssertTrue(didSink)  // 4
}
  1. 使用虚拟时间调度器需要在测试开始时创建一个,将其时钟初始化为起始值。 EntwineTest 中的虚拟时间调度器将以 200 的值开始订阅,如果管道在时间为 900 时还没完成,则会超时。
  2. 你和以往创建任何发布者或订阅者一样,创建你的管道。 EntwineTest 还提供可测试的发布者和订阅者,以供使用。 有关 EntwineTest 这些部分的更多详细信息,请看 使用 EntwineTest 创建可测试的发布器和订阅者.
  3. .resume() 需要在虚拟时间调度器上调用,以开始其工作和触发管道运行。
  4. 在管道运行到完成后,对预期的最终结果进行断言。

参考

https://heckj.github.io/swiftui-notes/index_zh-CN.html

代码

https://github.com/heckj/swiftui-notes

这篇关于Swift Combine 使用从 PassthroughSubject 预定好的发送的事件测试订阅者 从入门到精通二十三的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/726794

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他