gpt4 book ai didi

ios - 如何测试 RxSwift Observable.interval 进度

转载 作者:搜寻专家 更新时间:2023-10-31 22:02:11 24 4
gpt4 key购买 nike

我有一个 View 模型,其行为由 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 ,我建议您将其作为依赖项注入(inject)。

另外,检查 _exerciseRemainingTime 的值, 你需要删除 private .但是,我不建议测试您类(class)的内部结构。删除 private是你是的标志。相反,如果您要注入(inject)一个负责执行 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从 View 模型。我认为这无论如何都会改进它,因为您应该订阅 View Controller 并且只使用 View 模型为您提供 Observable .这避免了 View 模型需要处理包和管理 Disposable 的生命周期。

你真的应该考虑公开一些比 _exerciseRemainingTime 更不“内部”的东西.也许像 currentExercise: Observable<ExerciseEnum> ,内部基于 _exerciseRemainingTime .这样,您的 View Controller 就可以订阅并执行简单的与 View Controller 相关的工作,以进入下一个练习。

此外,为了简化测试,您可以注入(inject) 20变量到 View 模型中,以便在测试中你可以提供更小的东西,比如 3然后 correct只需要几个元素的长度。

关于ios - 如何测试 RxSwift Observable.interval 进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38497874/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com