gpt4 book ai didi

unit-testing - 在 RxSwift 中测试 ViewModel

转载 作者:行者123 更新时间:2023-12-05 05:10:32 24 4
gpt4 key购买 nike

我想在我的一个 ViewModel 中执行测试,其中包含一个名为“nearByCity”的 BehaviorRelay 对象,它绑定(bind)到名为“isNearBy”的 BehaviorRelay。这就是我的 View 模型的样子。

class SearchViewViewModel: NSObject {

//MARK:- Properties
//MARK: Constants
let disposeBag = DisposeBag()


//MARK: Vars
var nearByCity:BehaviorRelay<String?> = BehaviorRelay(value: nil)
var isNearBy = BehaviorRelay(value: true)

//MARK:- Constructor
init() {

super.init()
setupBinders()

}

}


//MARK:- Private methods
private extension SearchViewViewModel{

func setupBinders(){

nearByCity
.asObservable()
.distinctUntilChanged()
.map({$0 ?? ""})
.map({$0 == ""})
.bind(to: isNearBy)
.disposed(by: disposeBag)

}

}

我想做的测试是实际验证当字符串被接受时,bool 值也会根据函数 setupBinders() 发生变化。

有什么想法吗?

谢谢

最佳答案

这是一种测试方法:

class RxSandboxTests: XCTestCase {

func testBinders() {
let scheduler = TestScheduler(initialClock: 0)
let source = scheduler.createColdObservable([.next(5, "hello"), .completed(10)])
let sink = scheduler.createObserver(Bool.self)
let disposeBag = DisposeBag()

let viewModel = SearchViewViewModel(appLocationManager: StubManager())
source.bind(to: viewModel.nearByCity).disposed(by: disposeBag)
viewModel.isNearBy.bind(to: sink).disposed(by: disposeBag)

scheduler.start()

XCTAssertEqual(sink.events, [.next(0, true), .next(5, false)])
}
}

其他几点:

  • 不要让您的主题属性 var 使用 let,因为您不希望任何人能够用未绑定(bind)的版本替换它们。

  • 您必须在此代码中使用 AppLocationManager 而不需要它的事实意味着该对象正在做太多事情。在 View Controller 中拥有多个 View 模型并分别处理 View 的不同部分并没有错。

  • 最好完全避免在您的 View 模型代码中使用主题(中继),如果需要,最好将它们留在代码的命令式部分。

至少,分解您的 setupBinders 函数,以便各个部分可以独立测试。你的上面可以写成一个简单的、容易测试的、免费的函数:

func isNearBy(city: Observable<String?>) -> Observable<Bool> {
return city
.distinctUntilChanged()
.map {$0 ?? ""}
.map {$0 == ""}
}

关于unit-testing - 在 RxSwift 中测试 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56541855/

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