Swift中无返回值异步函数单元测试不稳定(超时)问题求助
异步单元测试不稳定问题解决方法
问题根源
Interactor的markBookAsOpen方法内部创建了独立Task执行异步调用,测试中调用该方法后立即执行verify,此时异步任务可能还未完成,导致验证时机不匹配,出现时而通过时而超时失败的情况。
方法一:修改Interactor暴露异步接口(推荐)
将Interactor的方法改为异步,让测试代码可以明确等待任务执行完毕:
// 修改Interactor.swift func markBookAsOpen() async { await self.worker.logOpened(id: self.bookId) }
调整测试代码:
func test_markBookAsOpen_shouldCallAtWorker() async { // When await self.interactor.markBookAsOpen() // Then verify(await self.workerMock.logOpened(id: any(String.self))).wasCalled(1) }
方法二:用XCTestExpectation等待异步调用触发
如果无法修改Interactor方法,通过测试期望等待实际调用发生:
func test_markBookAsOpen_shouldCallAtWorker() async { let callExpectation = XCTestExpectation(description: "Worker logOpened method called") // 给Mock设置回调,触发期望 given(await workerMock.logOpened(id: any(String.self))).will { _ in callExpectation.fulfill() } // When self.interactor.markBookAsOpen() // 等待期望完成,超时时间可按需调整 await fulfillment(of: [callExpectation], timeout: 1.0) // Then verify(await self.workerMock.logOpened(id: any(String.self))).wasCalled(1) }
方法三:临时睡眠等待(不推荐)
如果以上方式无法实现,可临时通过固定时长等待异步任务调度,但依赖系统性能,仍可能不稳定:
func test_markBookAsOpen_shouldCallAtWorker() async { // When self.interactor.markBookAsOpen() // 等待100ms让异步任务执行 try? await Task.sleep(nanoseconds: 100 * 1_000_000) // Then verify(await self.workerMock.logOpened(id: any(String.self))).wasCalled(1) }
内容的提问来源于stack exchange,提问作者Nawin P.
相关产品推荐
相关产品推荐

