【发布时间】:2022-10-18 08:40:27
【问题描述】:
我想测试我的 init 函数是否按预期工作。 Task {} 块内的 init 中有一个异步调用。如何让我的测试等待任务块的结果?
class ViewModel: ObservableObject {
@Published private(set) var result: [Item]
init(fetching: RemoteFetching) {
self.result = []
Task {
do {
let result = try await fetching.fetch()
self.result = result // <- need to do something with @MainActor?
} catch {
print(error)
}
}
}
}
测试:
func testFetching() async {
let items = [Item(), Item()]
let fakeFetching = FakeFetching(returnValue: items)
let vm = ViewModel(fetching: FakeFetching())
XCTAssertEqual(vm.result, [])
// wait for fetching, but how?
XCTAssertEqual(vm.result, items])
}
我试过这个,但设置项目,只发生在 XCTWaiter 之后。编译器警告不能用 await 调用 XCTWaiter,因为它不是异步的。
func testFetching() async {
let items = [Item(), Item()]
let fakeFetching = FakeFetching(returnValue: items)
let expectation = XCTestExpectation()
let vm = ViewModel(fetching: FakeFetching())
XCTAssertEqual(vm.result, [])
vm.$items
.dropFirst()
.sink { value in
XCTAssertEqual(value, items)
expectation.fulfill()
}
.store(in: &cancellables)
let result = await XCTWaiter.wait(for: [expectation], timeout: 1)
XCTAssertEqual(result, .completed)
}
【问题讨论】:
-
等待和期望是正确的。你只是用错了。基本上你是在想太多了。您不需要
async测试方法。你不需要自己调用实现。您不需要组合链。只需使用谓词期望等待 vm.result 设置。
标签: swift concurrency