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
This comment has been minimized.
Hey @daehn, thanks a bazillion mate.