如何编写单元测试验证Swift异步函数未超时?
如何测试Swift异步函数是否不超时?
你原来的代码逻辑完全搞反了——try await loader.perform()会挂起当前任务直到异步操作完成,后续的wait(for:timeout:)根本没机会执行,而且expectation.fulfill()写在wait之后,永远不会被调用,自然导致测试卡住。
要检查异步函数是否在指定时间内完成,最简洁的方式是用Swift 5.7+引入的Task.withTimeout API,它会自动在超时后抛出错误,直接实现超时检查:
func testLoaderDoesNotTimeout() async throws { // 限制异步操作必须在1秒内完成 try await Task.withTimeout(1) { let result = try await loader.perform() XCTAssertEqual(result.value, 42) } }
原理说明:
Task.withTimeout(1)会创建带超时限制的任务,闭包内的loader.perform()如果在1秒内完成,就正常执行断言;- 如果超过1秒还没完成,
withTimeout会自动抛出CancellationError,测试直接失败,达到“检查不超时”的目的。
如果你需要兼容更早的Swift版本,也可以手动通过任务调度实现:
func testLoaderDoesNotTimeoutLegacy() async throws { let loaderTask = Task { try await loader.perform() } // 等待1秒 try await Task.sleep(nanoseconds: 1_000_000_000) if !loaderTask.isCompleted { XCTFail("loader.perform() 执行超时,超过1秒") loaderTask.cancel() // 取消未完成的任务 return } // 任务已完成,验证结果 let result = try await loaderTask.value XCTAssertEqual(result.value, 42) }
这种方式需要手动等待指定时间,再检查任务是否完成,虽然不如withTimeout简洁,但能适配旧版本Swift。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

