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

Swift Testing中如何实现类似XCTest的NotificationCenter通知测试

在Swift Testing中测试NSNotificationCenter通知的实现方法

问题背景

在XCTest中,我们可以通过expectation(forNotification:)方法便捷测试NSNotificationCenter的通知发送逻辑,示例代码如下:

func testLoginNotification() {
    let notificationExpectation = expectation(forNotification: .login, object: nil, handler: nil)

    methodPostNotificationLogin()

    wait(for: [notificationExpectation], timeout: 2)
}

现需在Swift Testing框架中编写等价的通知测试代码,已有测试函数框架如下:

@Test fun loginNotification() {
   #expect()
}

实现方案

Swift Testing框架没有提供直接对应XCTest的通知期望API,需通过手动监听通知结合异步等待与断言来实现,完整代码如下:

@Test func loginNotification() async {
    // 创建异步等待的Continuation,监听目标通知
    let notificationReceived = withCheckedContinuation { continuation in
        let observer = NotificationCenter.default.addObserver(
            forName: .login,
            object: nil,
            queue: .main
        ) { _ in
            continuation.resume()
        }
        // 测试结束后自动移除观察者,避免内存泄漏
        continuation.onTermination = { _ in
            NotificationCenter.default.removeObserver(observer)
        }
    }

    // 触发发送通知的业务方法
    methodPostNotificationLogin()

    // 设置超时等待,并验证通知是否触发
    do {
        try await withTimeout(.seconds(2)) {
            await notificationReceived
        }
        #expect(true, "登录通知未正常触发")
    } catch {
        #expect(false, "等待登录通知超时(超过2秒)")
    }
}

关键说明

  • 异步等待逻辑:通过withCheckedContinuation将通知监听转换为可等待的异步任务,收到通知后恢复任务执行
  • 资源清理:利用continuation.onTermination在测试结束时移除通知观察者,避免内存泄漏
  • 超时控制:使用withTimeout模拟XCTest中wait(for:timeout:)的超时机制,确保测试不会无限等待
  • 断言验证:通过#expect()分别验证通知正常触发和超时两种场景的结果

内容的提问来源于stack exchange,提问作者William Hu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:52:39