gpt4 book ai didi

ios - Swift 中的单元测试 fatalError

转载 作者:IT王子 更新时间:2023-10-29 05:07:24 25 4
gpt4 key购买 nike

如何在 Swift 中对 fatalError 代码路径进行单元测试?

例如,我有以下swift代码

func divide(x: Float, by y: Float) -> Float {

guard y != 0 else {
fatalError("Zero division")
}

return x / y
}

我想在 y = 0 时对案例进行单元测试。

请注意,我想使用 fatalError 而不是任何其他断言函数。

最佳答案

想法是用您自己的函数替换内置的 fatalError 函数,该函数在单元测试执行期间被替换,以便您在其中运行单元测试断言。

然而,棘手的部分是 fatalError@noreturn,因此您需要用一个永不返回的函数覆盖它。

重写 fatal error

仅在您的应用目标中(不要添加到单元测试目标):

// overrides Swift global `fatalError`
@noreturn func fatalError(@autoclosure message: () -> String = "", file: StaticString = __FILE__, line: UInt = __LINE__) {
FatalErrorUtil.fatalErrorClosure(message(), file, line)
unreachable()
}

/// This is a `noreturn` function that pauses forever
@noreturn func unreachable() {
repeat {
NSRunLoop.currentRunLoop().run()
} while (true)
}

/// Utility functions that can replace and restore the `fatalError` global function.
struct FatalErrorUtil {

// Called by the custom implementation of `fatalError`.
static var fatalErrorClosure: (String, StaticString, UInt) -> () = defaultFatalErrorClosure

// backup of the original Swift `fatalError`
private static let defaultFatalErrorClosure = { Swift.fatalError($0, file: $1, line: $2) }

/// Replace the `fatalError` global function with something else.
static func replaceFatalError(closure: (String, StaticString, UInt) -> ()) {
fatalErrorClosure = closure
}

/// Restore the `fatalError` global function back to the original Swift implementation
static func restoreFatalError() {
fatalErrorClosure = defaultFatalErrorClosure
}
}

扩展

将以下扩展添加到您的单元测试目标:

extension XCTestCase {
func expectFatalError(expectedMessage: String, testcase: () -> Void) {

// arrange
let expectation = expectationWithDescription("expectingFatalError")
var assertionMessage: String? = nil

// override fatalError. This will pause forever when fatalError is called.
FatalErrorUtil.replaceFatalError { message, _, _ in
assertionMessage = message
expectation.fulfill()
}

// act, perform on separate thead because a call to fatalError pauses forever
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), testcase)

waitForExpectationsWithTimeout(0.1) { _ in
// assert
XCTAssertEqual(assertionMessage, expectedMessage)

// clean up
FatalErrorUtil.restoreFatalError()
}
}
}

测试用例

class TestCase: XCTestCase {
func testExpectPreconditionFailure() {
expectFatalError("boom!") {
doSomethingThatCallsFatalError()
}
}
}

我从这篇关于单元测试 assertprecondition 的帖子中得到灵感: Testing assertion in Swift

关于ios - Swift 中的单元测试 fatalError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32873212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com