这是我第一次使用 RxTest ,我正在努力执行以下方法:
protocol ViewModelType {
func transform(input: ViewModel.Input) -> ViewModel.Output
}
struct ViewModel: ViewModelType {
private let isLoading = PublishSubject<Bool>()
struct Input {
let trigger: PublishSubject<Void>
}
struct Output {
let someAction: Observable<Void>
let isLoading: Observable<Bool>
}
func transform(input: Input) -> Output {
let someAction = input
.trigger
.do(onNext: { _ in
self.isLoading.onNext(true)
//do some async task
self.isLoading.onNext(false)
})
return Output(someAction: someAction, isLoading: isLoading)
}
}
我已经在viewModel内部创建了一个发布主题,以通知视图何时应显示加载器。
一切正常,除了我不知道如何使用RxTest框架进行测试。
我试图使用调度程序和冷观测器,但无法使其正常工作。
我想拥有的东西
也许,isLoading是我做的方式,这是不可测试的。但看来它正在通过输出解决,我认为也许有某种方法。
非常感谢您,如果不清楚,请随时进行编辑或指导我提出更好的问题。非常感谢。
答案 0 :(得分:1)
几件事:
您的Input
结构应包含可观察对象,而不是主题。这样,您就可以正确地附加它们。
您不想使用do
运算符。而是先从输出考虑问题。当触发器发出时,您希望isLoading发出true,并且您要启动异步任务。这意味着您应该有两个可观察的链。有很多示例代码显示了如何执行此操作。
同时,这是您的测试(以及对代码的必要修改:
class RxSandboxTests: XCTestCase {
func testOne() {
let scheduler = TestScheduler(initialClock: 0)
let trigger = scheduler.createHotObservable([.next(10, ())])
let someActionResult = scheduler.createObserver(Bool.self)
let isLoadingResult = scheduler.createObserver(Bool.self)
let bag = DisposeBag()
let sut = ViewModel()
let input = ViewModel.Input(trigger: trigger.asObservable())
let output = sut.transform(input: input)
bag.insert(
output.someAction.map { true }.bind(to: someActionResult),
output.isLoading.bind(to: isLoadingResult)
)
scheduler.start()
XCTAssertEqual(someActionResult.events, [.next(10, true)])
XCTAssertEqual(isLoadingResult.events, [.next(10, true), .next(10, false)])
}
}
protocol ViewModelType {
func transform(input: ViewModel.Input) -> ViewModel.Output
}
struct ViewModel: ViewModelType {
private let isLoading = PublishSubject<Bool>()
struct Input {
let trigger: Observable<Void>
}
struct Output {
let someAction: Observable<Void>
let isLoading: Observable<Bool>
}
func transform(input: Input) -> Output {
let someAction = input
.trigger
.do(onNext: { _ in
self.isLoading.onNext(true)
//do some async task
self.isLoading.onNext(false)
})
return Output(someAction: someAction, isLoading: isLoading)
}
}