如何解决如何在Swift中测试异步调度的方法
我需要为以下方法编写单元测试
func setLabelText(msg: String) {
dispatchQueue.main.async {
self.label.text = msg
}
}
解决方法
让我们假设您的测试设置已经创建了一个视图控制器,并调用loadViewIfNeeded()
连接任何插座。 (这是来自第5章,“加载视图控制器”。)并且该视图控制器位于一个属性中,我将其命名为sut
(表示被测系统)。
如果您编写了一个测试用例以调用setLabelText(msg:)
,然后立即检查视图控制器的标签,则将无法使用。
如果您已调度到后台线程,那么我们需要测试以等待线程完成。但这不是这种代码。
您的生产代码从后台调用setLabelText(msg:)
。但是测试代码在主线程上运行。因为它已经在主线程上,所以我们要做的就是再执行一次运行循环。您可以使用帮助功能来表达这一点,我将在第10章“测试屏幕之间的导航:”中介绍
func executeRunLoop() {
RunLoop.current.run(until: Date())
}
有了这个,这是一个有效的测试:
func test_setLabelText_thenExecutingMainRunLoop_shouldUpdateLabel() throws {
sut.setLabelText(msg: "TEST")
executeRunLoop()
XCTAssertEqual(sut.label.text,"TEST")
}
这成功地测试了方法,并且很快完成。但是,如果另一个程序员出现并更改setLabelText(msg:)
,将self.label.text = msg
调用拉到DispatchQueue.main.async
之外怎么办?我在第13章“测试网络响应(和关闭)”中的“在关闭中保留异步代码”一节中描述了此问题。基本上,我们要测试在未运行分派的闭包时标签没有更改。我们可以通过第二项测试来做到这一点:
func test_setLabelText_withoutExecutingMainRunLoop_shouldNotUpdateLabel() throws {
sut.label.text = "123"
sut.setLabelText(msg: "TEST")
XCTAssertEqual(sut.label.text,"123")
}
,
在我看来,使用XCTestExpectation
的Hello可能会受益,因为该API旨在测试异步操作(您可以了解更多关于here的信息)
就两者之间的比较而言,我唯一想到的就是使用XCTestExpectation
可以测试服务器超时(假设您的api在预期的时间内没有响应。URLSession具有一个默认时间超过60秒),并带有特定的错误代码和消息。
您可以将完成闭包添加到displayMessage并在测试中调用Expectation.fulfill()。另一种完全不同的方法是实现某种演示设计模式,例如协调器或演示者。在这种情况下,您的所有UI演示都将抽象为非异步方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。