如何在Swift Testing框架的单元测试中验证assertionFailure()的触发
如何在Swift Testing框架的单元测试中验证assertionFailure()的触发
没问题,这在Swift Testing框架里完全可以实现,我来给你一步步讲清楚怎么做~
首先得说下:默认情况下,assertionFailure在测试环境里会直接终止测试流程,所以我们得用点手段捕获它的触发行为,而不是让测试直接挂掉。下面有两种常用的实现方式,你可以根据项目情况选:
方式一:临时替换全局assertionFailure函数
因为assertionFailure是全局函数,我们可以在当前测试的作用域内临时替换它的实现,记录它是否被调用,测试结束后再恢复原实现,不会影响其他测试用例。
代码示例:
@Test func testFooTriggersAssertionFailureWhenBarIsFalse() { // 标记断言是否被触发 var didTriggerAssertionFailure = false // 保存原有的assertionFailure实现 let originalAssertionFailure = assertionFailure // 替换全局的assertionFailure为我们自定义的闭包 assertionFailure = { message, file, line in didTriggerAssertionFailure = true // 可选:如果想保留原有的断言失败行为(比如在控制台输出信息),可以调用原实现 originalAssertionFailure(message, file: file, line: line) } // 测试结束后恢复原实现,必须做这一步! defer { assertionFailure = originalAssertionFailure } // 调用被测试的函数 _ = foo(bar: false) // 验证断言是否被触发 #expect(didTriggerAssertionFailure, "Expected assertionFailure to be triggered when bar is false") }
这个方法的好处是兼容性强,不管你用的是哪个版本的Swift Testing都能跑,而且逻辑直白,容易理解。
方式二:用Swift Testing自带的withAssertionCatcher(iOS 17+/macOS 14+及以上可用)
如果你用的是比较新的系统版本,Swift Testing提供了更优雅的API——withAssertionCatcher,它可以自动捕获作用域内所有的断言失败(包括assertionFailure、assert等),返回一个包含断言信息的数组,我们直接验证数组的内容就行。
代码示例:
@Test func testFooTriggersAssertionFailureWhenBarIsFalse() { // 捕获闭包内的所有断言失败 let caughtAssertions = withAssertionCatcher { _ = foo(bar: false) } // 验证捕获到的断言数量和具体信息 #expect(caughtAssertions.count == 1, "Expected exactly one assertion failure") #expect(caughtAssertions.first?.message == "expected true but was false", "Assertion message doesn't match expected value") }
这种方法更符合Swift Testing的原生风格,不需要手动替换全局函数,代码更简洁,还能直接验证断言的具体消息,推荐在支持的版本里使用。
另外要注意:如果你选择保留原assertionFailure的行为(方式一里的originalAssertionFailure调用),测试时控制台会输出断言失败的信息,这是正常的,不影响测试结果的判断。
备注:内容来源于stack exchange,提问作者Levan Karanadze
相关产品推荐
相关产品推荐

