我正在尝试测试我的 ViewModel 的主要功能。重要的步骤是测试加载状态完成。但可以肯定的是,为了更好的测试,测试所有状态可能会很有趣。
我正在阅读很多关于 RxTest 和 RxBlocking 的帖子和信息,但我无法测试这个模块。如果有人可以帮助我,那就太好了!
struct Product: Equatable { }
struct Promotion { }
protocol ProductsRepository {
func fetchProducts() -> Observable<Products>
func fetchPromotions() -> Observable<[Promotion]>
}
struct ProductCellViewModel: Equatable {
let product: Product
}
struct Products {
let products: [Product]
}
enum ProductsViewState: Equatable {
case loading
case empty
case error
case loaded ([ProductCellViewModel])
}
class ProductsViewModel {
var repository: ProductsRepository
let disposeBag = DisposeBag()
private var productCellViewModel: [ProductCellViewModel]
private var promotions: [Promotion]
// MARK: Input
init(repository: ProductsRepository) {
self.repository = repository
productCellViewModel = [ProductCellViewModel]()
promotions = [Promotion]()
}
func requestData(scheduler: SchedulerType) {
state.onNext(.loading)
resetCalculate()
repository.fetchProducts()
.observeOn(scheduler)
.flatMap({ (products) -> Observable<[ProductCellViewModel]> in
return self.buildCellViewModels(data: products)
}).subscribe(onNext: { (cellViewModels) in
self.productCellViewModel = cellViewModels
}, onError: { (error) in
self.state.onNext(.error)
}, onCompleted: {
self.repository.fetchPromotions()
.flatMap({ (promotions) -> Observable<[Promotion]> in
self.promotions = promotions
return Observable.just(promotions)
}).subscribe(onNext: { (_) in
self.state.onNext(.loaded(self.productCellViewModel))
}, onError: { (error) in
self.state.onNext(.error)
}).disposed(by: self.disposeBag)
}).disposed(by: disposeBag)
}
// MARK: Output
var state = PublishSubject<ProductsViewState>()
// MARK: ViewModel Map Methods
private func buildCellViewModels(data: Products) -> Observable <[ProductCellViewModel]> {
var viewModels = [ProductCellViewModel]()
for product in data.products {
viewModels.append(ProductCellViewModel.init(product: product))
}
return Observable.just(viewModels)
}
func resetCalculate() {
productCellViewModel = [ProductCellViewModel]()
}
}
目标是能够在调用 viewmodel.requestData() 之后测试所有 ProductsViewState