在RxSwift中测试ViewModel

时间:2019-06-11 10:38:21

标签: unit-testing rx-swift rxtest

我想在一个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()函数而改变。

有什么想法吗?

谢谢

1 个答案:

答案 0 :(得分:1)

这是一种测试方法:

  path('group_edit/<int:group_id>/', views.group_edit, name='group-edit'),
    path('confirm_delete/<int:group_id>/', views.confirm_delete, name='confirm-delete'),
    path('group_list/', views.group_list, name='group-list'),

其他几点:

  • 不要让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而不需要使用它这一事实表明该对象做得太多。在视图控制器中具有多个视图模型并没有错,每个模型都处理视图的不同部分。

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

至少,请破坏您的setupBinders函数,以便可以独立测试零件。您的上面代码可能被编写为简单,易于测试的免费功能:

AppLocationManager