ExpectToEventuallyEqual 是一个用于异步代码的 XCTest 断言。
假设我们有一个从视图模型读取数据的表格视图。视图模型决定了表格中的行数
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
results.count
}
表格视图控制器的 viewDidLoad() 方法告诉视图模型加载数据,然后重新加载表格数据。 因为 load() 是异步的,所以我们等待它的结果并将它包装在 Task 中。
Task {
results = await viewModel.load()
self.tableView.reloadData()
}
如果此 Task 包含对闭包的调用,则测试可以等待 XCTestExpectation 并注入一个闭包,该闭包调用期望上的 fulfill()。 因此,测试此方法的一种方法是添加一个完成闭包,该闭包在数据重新加载后触发。
另一种方法是以周期性间隔检查某些条件。 在将两个结果存根到视图模型后,这是一个 expectToEventuallyEqual 断言,它检查行数最终是否为 2
try await expectToEventuallyEqual(
actual: { tableDataSource.tableView(sut.tableView, numberOfRowsInSection: 0) },
expected: 2
)
该断言重复计算 actual 闭包,并将其与 expected 值进行比较。 只要它们相等,此断言就会通过。 如果超时且值仍然不相等,则断言失败。
有一个 SampleApp 你可以尝试查看一些通过的测试和一个失败的测试。
如果您有一个 Project.swift 文件,请声明以下依赖项
dependencies: [
.package(url: "https://github.com/jonreid/ExpectToEventuallyEqual", from: "1.0.0"),
],
然后将其添加到您的测试目标中
.testTarget(
name: "MyTests",
dependencies: [
"ExpectToEventuallyEqual",
],
允许 actual 闭包抛出异常。
actual 闭包和 expected 值必须计算为相同的 Equatable 类型。
默认 timeout 为 1 秒。您可以指定不同的值。
每次比较后,RunLoop 会短暂运行以处理线程上的其他事件。
失败时,断言报告预期值和最后实际值。 如果它们是字符串,则这些值显示在双引号中,以下字符表示为转义特殊字符
Jon Reid 和 Steven Baker 在一起教授 iOS 研讨会时创建了这个断言。