RxSwift 测试现在失败。引入了延迟
RxSwift Test fails now .delay has been introduced
我有以下代码 -
viewIsReady
.flatMapLatest { [unowned self] _ in self.dependencies.authSvc.checkSession().asDriver(onErrorJustReturn: false) }
.distinctUntilChanged()
.delay(.seconds(2), scheduler: MainScheduler.instance) <-- without this test passes
.bind(to: checkSessionComplete)
.disposed(by: disposeBag)
我们有一个显示的初始视图,并且希望每次显示它的时间最短。由于这个视图通过发送到 checkSessionComplete
被取消,我添加了一个延迟,以允许异步操作完成并防止序列继续移动。
但是现在测试失败了,但是行为是正确的。
我应该如何测试包含 delay
运算符的操作?
func test_on_check_session_response_emits() {
let deps = TestDependencies()
deps.authSvcSpy.stubbedCheckSessionResult = .just(true)
DependencyInjector.dependencies = deps
scheduler.scheduleAt(0) {
self.sut.viewIsReady.onNext(())
}
let observer = scheduler.createObserver(AuthState.self)
sut.checkSessionComplete
.asObservable()
.bind(to: observer)
.disposed(by: disposeBag)
scheduler.start()
XCTAssertEqual(observer.events.count, 1)
}
编辑
根据下面的回答,我更新了我的 Presenter
-
final class StartPresenter {
// Input
let viewIsReady = PublishSubject<Void>()
// Output
let checkSessionComplete = PublishSubject<Void>()
var scheduler: SchedulerType = MainScheduler.instance
weak private var view: StartViewInterface?
private lazy var disposeBag = DisposeBag()
init(view: StartViewInterface?) {
self.view = view
viewIsReady
.flatMapLatest { [unowned self] _ in self.dependencies.authSvc.checkSession().asDriver(onErrorJustReturn: false) }
.distinctUntilChanged()
.mapToVoid()
.delay(.seconds(2), scheduler: scheduler)
.bind(to: checkSessionComplete)
.disposed(by: disposeBag)
}
}
和我的测试用例
func test_on_check_session_response_emits() {
let deps = TestDependencies()
deps.authSvcSpy.stubbedCheckSessionResult = .just(true)
DependencyInjector.dependencies = deps
sut.scheduler = testScheduler
testScheduler.scheduleAt(0) {
self.sut.viewIsReady.onNext(())
}
let observer = testScheduler.createObserver(Void.self)
sut.checkSessionComplete
.asObservable()
.delay(.seconds(2), scheduler: testScheduler)
.bind(to: observer)
.disposed(by: disposeBag)
testScheduler.start()
XCTAssertEqual(observer.events.count, 1)
}
}
如果 .delay
在链中,测试仍然失败。
在您的代码中,您使用的是 MainScheduler.instance
,这在测试期间不起作用。您需要注入测试调度程序并使用该调度程序,例如:.delay(.seconds(2), scheduler: scheduler)
.
我有以下代码 -
viewIsReady
.flatMapLatest { [unowned self] _ in self.dependencies.authSvc.checkSession().asDriver(onErrorJustReturn: false) }
.distinctUntilChanged()
.delay(.seconds(2), scheduler: MainScheduler.instance) <-- without this test passes
.bind(to: checkSessionComplete)
.disposed(by: disposeBag)
我们有一个显示的初始视图,并且希望每次显示它的时间最短。由于这个视图通过发送到 checkSessionComplete
被取消,我添加了一个延迟,以允许异步操作完成并防止序列继续移动。
但是现在测试失败了,但是行为是正确的。
我应该如何测试包含 delay
运算符的操作?
func test_on_check_session_response_emits() {
let deps = TestDependencies()
deps.authSvcSpy.stubbedCheckSessionResult = .just(true)
DependencyInjector.dependencies = deps
scheduler.scheduleAt(0) {
self.sut.viewIsReady.onNext(())
}
let observer = scheduler.createObserver(AuthState.self)
sut.checkSessionComplete
.asObservable()
.bind(to: observer)
.disposed(by: disposeBag)
scheduler.start()
XCTAssertEqual(observer.events.count, 1)
}
编辑
根据下面的回答,我更新了我的 Presenter
-
final class StartPresenter {
// Input
let viewIsReady = PublishSubject<Void>()
// Output
let checkSessionComplete = PublishSubject<Void>()
var scheduler: SchedulerType = MainScheduler.instance
weak private var view: StartViewInterface?
private lazy var disposeBag = DisposeBag()
init(view: StartViewInterface?) {
self.view = view
viewIsReady
.flatMapLatest { [unowned self] _ in self.dependencies.authSvc.checkSession().asDriver(onErrorJustReturn: false) }
.distinctUntilChanged()
.mapToVoid()
.delay(.seconds(2), scheduler: scheduler)
.bind(to: checkSessionComplete)
.disposed(by: disposeBag)
}
}
和我的测试用例
func test_on_check_session_response_emits() {
let deps = TestDependencies()
deps.authSvcSpy.stubbedCheckSessionResult = .just(true)
DependencyInjector.dependencies = deps
sut.scheduler = testScheduler
testScheduler.scheduleAt(0) {
self.sut.viewIsReady.onNext(())
}
let observer = testScheduler.createObserver(Void.self)
sut.checkSessionComplete
.asObservable()
.delay(.seconds(2), scheduler: testScheduler)
.bind(to: observer)
.disposed(by: disposeBag)
testScheduler.start()
XCTAssertEqual(observer.events.count, 1)
}
}
如果 .delay
在链中,测试仍然失败。
在您的代码中,您使用的是 MainScheduler.instance
,这在测试期间不起作用。您需要注入测试调度程序并使用该调度程序,例如:.delay(.seconds(2), scheduler: scheduler)
.