Created
July 9, 2019 14:44
-
-
Save daehn/6f1f2ebff270b26a1137c4cf167e1e26 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey @daehn, thanks a bazillion mate.