加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在Swift中单元测试fatalError

发布时间:2020-12-14 05:37:35 所属栏目:百科 来源:网络整理
导读:如何在 Swift中执行fatalError代码路径的单元测试? 例如,我有以下swift代码 func divide(x: Float,by y: Float) - Float { guard y != 0 else { fatalError("Zero division") } return x / y} 当y = 0时,我想单位测试的情况. 注意,我想使用fatalError不是任
如何在 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,所以你需要用一个永远不会返回的函数来覆盖它.

覆盖fatalError

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

// 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,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()
        }
    }
}

我从这篇文章中得到了关于单元测试断言和前提条件的想法:
Testing assertion in Swift

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读