Как выполнить функции тестового броска в Swift?
Как протестировать функцию в Swift 2.0 бросках или нет? Как утверждать, что ErrorType
правильный ErrorType
?
Ответы
Ответ 1
EDIT: обновлен код для Swift 4.1
.
Здесь последняя версия Swift Fyodor Volchyok отвечает, кто использовал 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)
}
}
Если в вашем перечислении 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
}
}
Ответ 2
По крайней мере, в Xcode 7.3 (возможно, раньше) вы могли бы использовать встроенный XCTAssertThrowsError()
:
XCTAssertThrowsError(try methodThatThrows())
Если во время теста ничего не выдается, вы увидите что-то вроде этого:
Если вы хотите проверить, имеет ли выброшенная ошибка какой-то конкретный тип, вы можете использовать параметр 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)
}
Ответ 3
Учитывая следующие функции и декларации:
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
}
}
Эта функция FifthError
если 5 дается функции и FirstError
если FirstError
1.
Чтобы проверить, что функция успешно запускает unit тест, может выглядеть следующим образом:
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
-statement. Это не лучший способ по сравнению с другими языками.
Вы должны убедиться, что вы...
-
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")
}
Ответ 4
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."))
}
}
Ответ 5
Вы можете использовать эту функцию:
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)