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 ErrorType
is 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 Error
enum has associated values, you can either have your Error
enum conform to Equatable
, or use the if case
statement:
如果您的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 errorHandler
parameter 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 FifthError
if 5 is given to the function and FirstError
if 1 is given.
FifthError
如果给函数 5 并且给定FirstError
1,则此函数将抛出一个。
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 ErrorType
the 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 ErrorType
it'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...
你必须确保你...
return
in thecatch
for the correctErrorType
XCTFail()
andreturn
for all othercatch
XCTFail()
if nocatch
is executed
return
在catch
为了正确ErrorType
XCTFail()
和return
所有其他catch
XCTFail()
如果没有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:
例子:
##代码##