[英]How to test RxSwift Observable.interval progress
我有一個視圖模型,其行為由Observable.interval
控制。 實質上,它會在每個next
更新計時器標簽,並在一段時間后更新另一個值。
一個修剪過的例子:
class WorkoutViewModel {
private var _oneSecondTimer: Observable<Int> {
return Observable<Int>.interval(1, scheduler: MainScheduler.instance)
}
private let _exerciseRemainingTime: Variable<Int> = Variable(20)
func setupBehaviour() {
_oneSecondTimer.subscribeNext() { [unowned self] _ in
self._exerciseRemainingTime.value -= 1
if self._exerciseRemainingTime.value == 0 {
self.progressToNextExercise()
}
}
}
}
我想對此進行測試,以觀察事件的時間和_exerciseRemainingTime
值。
有沒有辦法如何使用TestScheduler
來模擬_oneSecondTimer
會打勾的虛擬時間?
是的,看看這個有你正在尋找的行為的簡單測試: https : //github.com/ReactiveX/RxSwift/blob/b3f4bf1/Tests/RxSwiftTests/Tests/Observable+TimeTest.swift#L496
要將TestScheduler
交換為MainScheduler
,我建議您將其作為依賴項注入。
另外,要檢查_exerciseRemainingTime
的值,您需要刪除private
。 但是,我不建議測試你班級的內部。 刪除private
是你的標志。 相反,如果您要注入一個負責執行progressToNextExercise
的對象,那么您可以測試它是否已接到調用以進行下一個練習。 您只需在測試期間傳入該對象的測試版本,就像使用TestScheduler
作為調度程序一樣。 這樣就無需公開_exerciseRemainingTime
來測試它,甚至不知道它。
但是,為了這個問題的主要目的,忽略了_exerciseRemainingTime
的可見性,這就是我對調度程序的意思:
WorkoutViewModel.swift
class WorkoutViewModel {
private var _oneSecondTimer: Observable<Int> {
return Observable<Int>.interval(1, scheduler: scheduler)
}
// not `private` anymore. also, a computed property
var _exerciseRemainingTime: Observable<Int> {
return self._oneSecondTimer.map { i in
20 - i
}
}
// injected via `init`
private let scheduler: SchedulerType
init(scheduler: SchedulerType) {
self.scheduler = scheduler
}
}
WorkoutViewModelTest.swift
func testExerciseRemainingTime() {
let scheduler = TestScheduler(initialClock: 0)
let res = scheduler.start(0, subscribed: 0, disposed: 23) {
WorkoutViewModel(scheduler: scheduler)._exerciseRemainingTime
}
let correct = [
next(1, 20), // output .Next(20) at 1 second mark
next(2, 19), // output .Next(19) at 2 second mark
next(3, 18),
next(4, 17),
next(5, 16),
next(6, 15),
next(7, 14),
next(8, 13),
next(9, 12),
next(10, 11),
next(11, 10),
next(12, 9),
next(13, 8),
next(14, 7),
next(15, 6),
next(16, 5),
next(17, 4),
next(18, 3),
next(19, 2),
next(20, 1),
next(21, 0),
next(22, -1),
]
XCTAssertEqual(res.events, correct)
}
要考慮幾個注意事項:
為了讓測試調度程序訂閱和處置,我從視圖模型中刪除了subscribeNext
。 我認為這無論如何都會改進它,因為您應該使用視圖控制器訂閱並且僅使用視圖模型為您提供Observable
。 這消除了視圖模型需要具有配置包並管理Disposable
的生命周期的需要。
你應該考慮暴露比_exerciseRemainingTime
更少“內部”的_exerciseRemainingTime
。 也許類似於currentExercise: Observable<ExerciseEnum>
,它在內部基於_exerciseRemainingTime
。 這樣,您的視圖控制器可以訂閱並執行與視圖控制器相關的簡單工作,即可進行下一個練習。
另外,為了簡化測試,您可以將20
變量注入到視圖模型中,這樣在測試中您可以提供更小的東西,如3
,然后correct
只需要幾個元素長。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.