我正在监听发布者的更改,然后在我的管道中异步获取一些数据并使用结果更新视图。但是,我不确定如何使它可测试。我怎样才能最好地等到期望得到满足?
看法
struct ContentView: View {
@StateObject var viewModel = ContentViewModel()
var body: some View {
NavigationView {
List(viewModel.results, id: \.self) {
Text($0)
}
.searchable(text: $viewModel.searchText)
}
}
}
视图模型
final class ContentViewModel: ObservableObject {
@Published var searchText: String = ""
@Published var results: [String] = []
private var cancellables = Set<AnyCancellable>()
init() {
observeSearchText()
}
func observeSearchText() {
$searchText
.dropFirst()
.debounce(for: 0.8, scheduler: DispatchQueue.main)
.sink { _ in
Task {
await self.fetchResults()
}
}.store(in: &cancellables)
}
private func fetchResults() async {
do {
try await Task.sleep(nanoseconds: 1_000_000_000)
self.results = ["01", "02", "03"]
} catch {
//
}
}
}
测试
class ContentViewTests: XCTestCase {
func testExample() {
// Given
let viewModel = ContentViewModel()
// When
viewModel.searchText = "123"
// Then (FAILS - Not waiting properly for result/update)
XCTAssertEqual(viewModel.results, ["01", "02", "03"])
}
}
当前的解决方法
如果我可以fetchResults()
使用,我可以异步/等待,这适用于我的单元和快照测试,但我担心:
- 如果不被外部调用,那么暴露是不好的做法?
- 我没有测试我的发布者管道
func testExample_Workaround() async {
// Given
let viewModel = ContentViewModel()
// When
await viewModel.fetchResults()
// Then
XCTAssertEqual(viewModel.results, ["01", "02", "03"])
}