【问题标题】:Testing ViewModel in RxSwift在 RxSwift 中测试 ViewModel
【发布时间】:2019-10-25 18:24:28
【问题描述】:

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

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)

    }

}

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

有什么想法吗?

谢谢

【问题讨论】:

  • RxTest 和 RxBlocking 用于测试。阅读一些关于他们的文章

标签: unit-testing rx-swift rxtest


【解决方案1】:

这是一种测试方法:

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,因为您不希望任何人能够用未绑定的版本替换它们。

  • 您必须在此代码中使用不需要它的AppLocationManager,这意味着该对象做的太多了。在一个视图控制器中拥有多个视图模型,每个模型处理视图的不同部分并没有错。

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

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

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

【讨论】:

  • 非常感谢您提供的信息和提示!是的,我要编辑这个问题,因为我确实从一个更大的类中提取了代码。
猜你喜欢
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多