I've encountered a problem with awaiting expectations in XCTestCase
when testing async code. I want to test code that is supposed to execute operations in background and notify me about the result.
The problem is that once background operation finishes nothing happens. Instead my expectation times out after the specified time. Below is a simplified model and test case that simulates my code. Running it displays only "before doSomethingAsync" and "in doSomethingAsync" messages in console. It looks to me like execution is not returning to main actor while waitForExpectations
is running.
@MainActor
final class ViewModel: ObservableObject {
let didRun: () -> Void
init(didRun: @escaping () -> Void) {
self.didRun = didRun
}
func doSomething() {
Task {
print("before doSomethingAsync")
await doSomethingAsync()
print("after doSomethingAsync")
didRun()
}
}
nonisolated func doSomethingAsync() async {
print("in doSomethingAsync")
}
}
final class AsyncTestTests: XCTestCase {
func testDoSomething() async throws {
let exp = expectation(description: "task finished")
let viewModel = await ViewModel(didRun: {
exp.fulfill()
})
await viewModel.doSomething()
await waitForExpectations(timeout: 5)
}
}
Is there anything that I'm doing incorrectly here or perhaps is it an issue with waitForExpectations
function?
I'm using Xcode 14.2 with iOS 16.2 simulator.