Skip to content

Instantly share code, notes, and snippets.

@daehn
Created July 9, 2019 14:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daehn/6f1f2ebff270b26a1137c4cf167e1e26 to your computer and use it in GitHub Desktop.
Save daehn/6f1f2ebff270b26a1137c4cf167e1e26 to your computer and use it in GitHub Desktop.
extension XCTestCase {
struct AwaitError: Error {}
/**
This function is useful for asynchronous testing and acts as a wrapper around test expectations.
Consider the following example:
```swift
// Let's asume we have an async function with the following signature:
func fetchLocations(_ completion: @escaping (Result<Location>) -> Void)
// In order to get the result without having to write explicit wait expectations
// we can now instead use the await function to get the result:
let result: Result<Location> = try await(fetchLocations)
// This also works with async functions that take other parameters than a completion closure:
func fetchLocations(maxCount: Int, completion: @escaping (Result<Location>) -> Void)
// Now we just have to forward the completion handler inside of the await closure:
let result: Result<Location> = try await { fetchLocations(maxCount: 25, completion: $0) }
```
If the compiler complains the most common issue is type inference and the easiest fix is to explicitly specify the
type of the result being returned from the await function.
- Parameter function: The asynchronous function which should be waited for and which result will be forwarded.
- Throws: An `AwaitError` if the wait fails before the function completion gets called.
- Returns: The value returned by the completion closure of the passed in function parameter.
*/
func await<T>(timeout: TimeInterval = 0.2, _ function: (@escaping (T) -> Void) -> Void) throws -> T {
var result: T?
let awaitExpectation = expectation(description: "It should call the function")
function {
result = $0
awaitExpectation.fulfill()
}
waitForExpectations(timeout: timeout, handler: nil)
guard let unrwapped = result else { throw AwaitError() }
return unrwapped
}
}
@skellock
Copy link

Hey @daehn, thanks a bazillion mate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment