What's the way to use `assertSnapshot` in async test?
valeriyvan opened this issue · comments
Please look below example of async test. Test with XCTAssertEqual
works as expected but same test with assertSnapshot
crashes.
What's the way to use assertSnapshot
in async test?
struct AsyncSequenceExample: AsyncSequence {
typealias Element = Int
func makeAsyncIterator() -> AsyncIterator {
print()
return AsyncIterator()
}
struct AsyncIterator: AsyncIteratorProtocol {
var current = 1
mutating func next() async throws -> Element? {
print("enter")
try await Task.sleep(nanoseconds: 100_000_000) // Simulate an asynchronous operation
defer { current += 1 }
guard Int.random(in: 0..<100_000_000) > 1_000_000 else {
return nil
}
print(current)
return current
}
}
}
class MyTests: XCTestCase {
func testAsyncSequence() async throws {
let asyncSequence = AsyncSequenceExample()
var result: [Int] = []
do {
for try await element in asyncSequence {
result.append(element)
}
} catch {
XCTFail("Unexpected error: \(error)")
}
// This test works as expected
// XCTAssertEqual(result, [1, 2, 3])
// But this crashes
assertSnapshot(of: result.description, as: .lines)
}
}
The problem is the use of XCTWaiter.wait inside of verifySnapshot. Using the synchronous wait function in an asynchronous context is a known issue (that's why Apple introduced await fulfillment(of:)
.
Is this crash Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Current context must not be nil'
? If so, I am hitting that issue too in an async test :/ is there any workaround that we can use until the library can be updated to support some sort of await assertSnapshot
method?
Actually, I did find that marking all the async
tests as @MainActor
works, so there's that... still frustrating but I suppose it works now :/