如何测试Swift 2.0中的函数是否抛出?如何断言抛出了正确的ErrorType
?
答案 0 :(得分:53)
EDIT: Updated the code for Swift 4.1
.
Here's the latest Swift version of Fyodor Volchyok's answer who used 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:
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
}
}
答案 1 :(得分:18)
至少Xcode 7.3(可能更早)你可以使用内置的XCTAssertThrowsError()
:
XCTAssertThrowsError(try methodThatThrows())
如果测试期间没有任何内容,你会看到类似的内容:
如果要检查抛出的错误是否属于某种具体类型,可以使用errorHandler
的{{1}}参数:
XCTAssertThrowsError()
答案 2 :(得分:9)
给出以下函数和声明:
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
}
}
如果给函数5,则此函数将抛出FifthError
,如果给出1,则抛出FirstError
。
要测试,成功运行单元测试的函数可能如下所示:
func testNotError() {
guard let _ = try? throwingFunction(2) else {
XCTFail("Error thrown")
return
}
}
let _
也可以替换为任何其他名称,因此您可以进一步测试输出。
断言函数抛出,无论ErrorType
单元测试如何:
func testError() {
if let _ = try? throwingFunction(5) {
XCTFail("No error thrown")
return
}
}
如果您想使用ErrorType
语句测试特定的do-catch
。与其他语言相比,这不是最佳方式。
你必须确保你......
return
在catch
中找到正确的ErrorType
所有其他XCTFail()
的return
和catch
如果没有执行XCTFail()
,则catch
鉴于此要求,测试用例可能如下所示:
func testFifthError() {
do {
try throwingFunction(5)
} catch SomeError.FifthError {
return
} catch {
XCTFail("Wrong error thrown")
return
}
XCTFail("No error thrown")
}
答案 3 :(得分:0)
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."))
}
}
答案 4 :(得分:0)
您可以使用此功能:
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 = $0
}
XCTAssertTrue(
thrownError is E,
"Unexpected error type: \(type(of: thrownError))",
file: file,
line: line
)
XCTAssertEqual(
thrownError as? E,
error,
file: file,
line: line
)
}
示例:
XCTAssertThrowsError(try funcThatThrowsSpecificError(), error: SpecificErrorEnum.someError)