swift2 如何对强制展开进行单元测试

wko9yo5t  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(168)

在Swift with XCTest中,是否可以测试强制解包的结果?我希望得到类似Jasmine的expect(...).toThrow()

let a: Something? = MAYBE_NIL_MAYBE_NOT

func unwrap()
{
    a!
}

XCTAssertCausesError(unwrap)
nwwlzxa7

nwwlzxa71#

使用新的XCTUnwrap来展开对象,并Assert值是否为nil。

let optional: String? = "optional"
let unwrapped: String = try XCTUnwrap(optional) // throws

在非抛出函数中,可以将guard用于测试失败单行程序,如下所示:

guard let unwrapped = try? XCTUnwrap(optional) else { return }

这与测试强制展开基本相同,只需使用函数而不是!
XCTUnwrapAssert可选变量的值不是nil,如果Assert成功,则返回其值。
这样就不需要将XCTAssertNotNil(_:_:file:line:)与展开值或处理测试其余部分的条件链接结合起来。例如:

func testFirstNameNotEmpty() throws {
    let forenames: [String] = customer.forenames

    let firstName =  try XCTUnwrap(forenames.first)
    XCTAssertFalse(firstName.isEmpty)
}

在WWDC 2019和Xcode 11发行说明中宣布:
https://developer.apple.com/documentation/xcode_release_notes/xcode_11_release_notes

ohtdti5x

ohtdti5x2#

根据swift的定义,你不可能捕捉到强制解包失败。而且,我不认为在生产代码中使用强制解包是一个好主意,除非你绝对确定它不会失败。
如果您使用以下命令,则可能会获得解包异常:

guard let a = a else { throw ... }

而不是a!

olqngx59

olqngx593#

我没有一个明确的答案,但苹果公司的文档对强制解包值说:
注记
尝试使用!访问不存在的可选值会触发运行时错误。在使用!强制展开可选值之前,请始终确保该可选值包含非空值。
swift语言(2.0)目前还没有语法来捕获这些runtime error。这些可能相当于分段错误/删除,而Objective-C的@try/@catch语法无法捕获这些错误。
看起来你是在测试语言本身的功能(比如强制解包nil值会抛出异常),而不是应用的逻辑。你最好像@Mario Zannone建议的那样捕获一个throw

let a: Something? = MAYBE_NIL_MAYBE_NOT

func unwrap(test: Any?)
{
    guard let value = test else {
        throw // an ErrorType
    }
}

XCTAssertCausesError(unwrap(a))

相关问题