触发一个事件并等待多个事件 RxTest
Trigger an event and wait for multiple events RxTest
这是我第一次使用 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 中创建了一个 Publish Subject 来通知视图何时应该显示加载器。
一切正常,只是我不知道如何使用 RxTest 框架对其进行测试。
我尝试使用调度程序和冷可观察对象,但无法使其正常工作。
我想要的:
- 使用调度程序将 .next(10, ()) 发送到触发器。
- 以某种方式记录 isLoading 的事件并断言先为真然后为假的相等。像这样:[.next(10, true), .next(20, false)].
也许,我做的isLoading,它是不可测试的。但似乎它正在通过输出输出,我想也许有一些方法。
非常感谢,如果有什么不清楚的地方,请随时编辑或指导我提出更好的问题。非常感谢。
几件事:
您的 Input
结构应该包含 Observables,而不是主题。这样你就可以正确地附加到它们。
您不想使用 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)
}
}
这是我第一次使用 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 中创建了一个 Publish Subject 来通知视图何时应该显示加载器。
一切正常,只是我不知道如何使用 RxTest 框架对其进行测试。
我尝试使用调度程序和冷可观察对象,但无法使其正常工作。
我想要的:
- 使用调度程序将 .next(10, ()) 发送到触发器。
- 以某种方式记录 isLoading 的事件并断言先为真然后为假的相等。像这样:[.next(10, true), .next(20, false)].
也许,我做的isLoading,它是不可测试的。但似乎它正在通过输出输出,我想也许有一些方法。
非常感谢,如果有什么不清楚的地方,请随时编辑或指导我提出更好的问题。非常感谢。
几件事:
您的 Input
结构应该包含 Observables,而不是主题。这样你就可以正确地附加到它们。
您不想使用 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)
}
}