xcode 如何在 Swift 中对抛出函数进行单元测试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32860338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to unit test throwing functions in Swift?
提问by Fabio Poloni
How to test wether a function in Swift 2.0 throws or not? How to assert that the correct ErrorTypeis thrown?
如何测试 Swift 2.0 中的函数是否抛出?如何断言正确ErrorType的抛出?
回答by Ferschae Naej
EDIT: Updated the code for Swift 4.1(still valid with Swift 5.2)
编辑:更新了代码Swift 4.1(仍然有效Swift 5.2)
Here's the latest Swift version of Fyodor Volchyok's answerwho used XCTAssertThrowsError:
这是Fyodor Volchyok 回答的最新 Swift 版本,他使用了XCTAssertThrowsError:
enum MyError: Error {
case someExpectedError
case someUnexpectedError
}
func functionThatThrows() throws {
throw MyError.someExpectedError
}
func testFunctionThatThrows() {
XCTAssertThrowsError(try functionThatThrows()) { error in
XCTAssertEqual(error as! MyError, MyError.someExpectedError)
}
}
If your Errorenum has associated values, you can either have your Errorenum conform to Equatable, or use the if casestatement:
如果您的Error枚举具有关联值,您可以让您的Error枚举符合Equatable,或使用以下if case语句:
enum MyError: Error, Equatable {
case someExpectedError
case someUnexpectedError
case associatedValueError(value: Int)
}
func functionThatThrows() throws {
throw MyError.associatedValueError(value: 10)
}
// Equatable pattern: simplest solution if you have a simple associated value that can be tested inside 1 XCTAssertEqual
func testFunctionThatThrows() {
XCTAssertThrowsError(try functionThatThrows()) { error in
XCTAssertEqual(error as! MyError, MyError.associatedValueError(value: 10))
}
}
// if case pattern: useful if you have one or more associated values more or less complex (struct, classes...)
func testFunctionThatThrows() {
XCTAssertThrowsError(try functionThatThrows()) { error in
guard case MyError.associatedValueError(let value) = error else {
return XCTFail()
}
XCTAssertEqual(value, 10)
// if you have several values or if they require more complex tests, you can do it here
}
}
回答by Fyodor Volchyok
At least of Xcode 7.3 (maybe earlier) you could use built-in XCTAssertThrowsError():
至少在 Xcode 7.3(可能更早)中,您可以使用 built-in XCTAssertThrowsError():
XCTAssertThrowsError(try methodThatThrows())
If nothing is thrown during test you'll see something like this:
如果在测试期间没有抛出任何内容,您将看到如下内容:
If you want to check if thrown error is of some concrete type, you could use errorHandlerparameter of XCTAssertThrowsError():
如果要检查抛出的错误是否属于某种具体类型,可以使用以下errorHandler参数XCTAssertThrowsError():
enum Error: ErrorType {
case SomeExpectedError
case SomeUnexpectedError
}
func functionThatThrows() throws {
throw Error.SomeExpectedError
}
XCTAssertThrowsError(try functionThatThrows(), "some message") { (error) in
XCTAssertEqual(error as? Error, Error.SomeExpectedError)
}
回答by Fabio Poloni
Given the following functions and declarations:
给定以下函数和声明:
enum SomeError: ErrorType {
case FifthError
case FirstError
}
func throwingFunction(x: Int) throws {
switch x {
case 1:
throw SomeError.FirstError
case 5:
throw SomeError.FifthError
default:
return
}
}
This function will throw a FifthErrorif 5 is given to the function and FirstErrorif 1 is given.
FifthError如果给函数 5 并且给定FirstError1,则此函数将抛出一个。
To test, that a function successfully runs the unit test could look as follows:
为了测试,一个函数成功运行单元测试可能如下所示:
func testNotError() {
guard let _ = try? throwingFunction(2) else {
XCTFail("Error thrown")
return
}
}
The let _may also be replaced by any other name, so you can further test the output.
该let _还可以通过任何其他名称代替,这样可以进一步测试输出。
To assert that a function throws, no matter what ErrorTypethe unit test could look like this:
断言一个函数抛出,不管ErrorType单元测试是什么样的:
func testError() {
if let _ = try? throwingFunction(5) {
XCTFail("No error thrown")
return
}
}
If you want to test for a specific ErrorTypeit's done with a do-catch-statement. This is not the best way compared to other languages.
如果你想测试一个特定的ErrorType它是用 -do-catch语句完成的。与其他语言相比,这不是最好的方法。
You have to make sure that you...
你必须确保你...
returnin thecatchfor the correctErrorTypeXCTFail()andreturnfor all othercatchXCTFail()if nocatchis executed
return在catch为了正确ErrorTypeXCTFail()和return所有其他catchXCTFail()如果没有catch被执行
Given this requirements a test case could look like this:
鉴于此要求,测试用例可能如下所示:
func testFifthError() {
do {
try throwingFunction(5)
} catch SomeError.FifthError {
return
} catch {
XCTFail("Wrong error thrown")
return
}
XCTFail("No error thrown")
}
回答by Declan McKenna
Swift 4.1 Error throwing Test for associated values
Swift 4.1 错误抛出关联值的测试
enum ParseError: Error, Equatable {
case unexpectedArgument(String)
}
func testWithNoSchemaButWithOneArgument() {
XCTAssertThrowsError(try Args(withSchema: "", andArguments: ["-x"])) { error in
XCTAssertEqual(error as? ParseError, ParseError.unexpectedArgument("Argument(s) -x unexpected."))
}
}
回答by Vitaliy Gozhenko
You can use this function:
您可以使用此功能:
func XCTAssertThrowsError<T, E: Error & Equatable>(
_ expression: @autoclosure () throws -> T,
error: E,
in file: StaticString = #file,
line: UInt = #line
) {
var thrownError: Error?
XCTAssertThrowsError(
try expression(),
file: file,
line: line) {
thrownError = XCTAssertThrowsError(try funcThatThrowsSpecificError(), error: SpecificErrorEnum.someError)
}
XCTAssertTrue(
thrownError is E,
"Unexpected error type: \(type(of: thrownError))",
file: file,
line: line
)
XCTAssertEqual(
thrownError as? E,
error,
file: file,
line: line
)
}
Example:
例子:
##代码##

