I'm trying to unit test some code that has a series of async operations (StoreKit code). I have to sink on a @Publisher and wait to get the right value, then call a method, and do it again. But it seems awaiting fulfillment doesn’t actually block execution:
In the following code, there are two await fulfillment(of:)
calls. I had expected the first one to wait until it was fulfilled, or until it timed out. But it does not, and the code immediately proceeds to delete the transaction it had created a bit earlier.
This is very counterintuitive to me. I can't imagine it's considered to be a bug, so is there another way for me to essentially stop the progress of a unit test until an @Published
property has a particular value?
let session = try SKTestSession(configurationFileNamed: "Re-Key")
session.clearTransactions()
let purchaseExpectation = XCTestExpectation(description: "purchaseExpectation")
let store = Store.shared
_ = store.$expires.sink
{ inValue in
if let hasSub = store.hasSubscription,
hasSub
{
purchaseExpectation.fulfill()
}
}
let txn = try await session.buyProduct(identifier: "rekey.lifetime")
await fulfillment(of: [purchaseExpectation], timeout: 5.0)
// Delete the purchase…
let deleteExpectation = XCTestExpectation(description: "deleteExpectation")
_ = store.$expires.sink
{ inValue in
if store.hasSubscription == nil
{
deleteExpectation.fulfill()
}
}
try session.deleteTransaction(identifier: UInt(txn.id))
await fulfillment(of: [deleteExpectation], timeout: 5.0)