Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Useful additions for common problems with XCTest
// XCTestCase+Unwrapping.swift
// Created by Zev Eisenberg on 6/2/19.
// Feel free to use, share, etc. No need to credit, but a link back to this page would be nice.
import XCTest
extension XCTestCase {
struct OptionalUnwrappingError: Error {
let file: StaticString
let line: UInt
/// Takes a throwing closure. Returns the result if the closure succeeds.
/// If the closure throws, this method registers an XCTest failure and rethrows the error.
/// - Note: closure comes last so that trailing closure syntax works.
func orFail<T>(file: StaticString = #file, line: UInt = #line, _ closure: () throws -> T) throws -> T {
do {
return try closure()
catch {
XCTFail("Function threw error: \(error)", file: file, line: line)
throw error
/// Unwraps the given optional value, or if it is nil,
/// throws an error and registers an XCTest failure.
/// Meant to be used in a test method that has been marked as `throws`.
/// - Note: Available in Xcode 11 as `XCTUnwrap`, so you should probably use that instead.
func unwrap<T>(_ optional: T?, file: StaticString = #file, line: UInt = #line) throws -> T {
guard let wrapped = optional else {
XCTFail("Optional was nil", file: file, line: line)
throw OptionalUnwrappingError(file: file, line: line)
return wrapped
/// Asserts that two errors are equal. Fails if they are not, or if the second one is not
/// `Equatable`. Works around the issue that most things in Swift deal with untyped errors,
/// so even if your error type is `Equatable`, it can be hard to check in tests that you
/// in fact have the right error.
func assertErrorsEqual<T: Error & Equatable>(
_ testError: Error,
_ controlError: T,
file: StaticString = #file,
line: UInt = #line
) {
guard let sameTypeError = testError as? T else {
"Expected error of type \(T.self), but got \(type(of: testError)): \(testError)",
file: file,
line: line)
XCTAssertEqual(sameTypeError, controlError)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.