You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 19:25:05