使用 RxSwift 测试 ViewModel

Posted

技术标签:

【中文标题】使用 RxSwift 测试 ViewModel【英文标题】:Testing ViewModel with RxSwift 【发布时间】:2016-01-06 19:51:37 【问题描述】:

我在我目前正在工作的项目中使用ModelView-ViewModel,并使用RxSwiftRxBlockingRxTests。目前我正在尝试测试 ViewModel,但在解决这个问题时遇到了很多麻烦。

假设我有一个ExampleViewModel 用于我的ExampleViewController。我的ExampleViewModel 期待一个Observable 流,它是来自UITextField 的两个流的组合(combineLatest),一个是textField 是聚焦的,另一个是文本流;所以像Observable<(Bool, String)>。根据是否聚焦和字符串的上下文,我的ExampleViewModel 将向其内部公开的属性发出一个事件,该属性是ObservableUITextField 的背景颜色的状态; Observable<UIColor>

ExampleViewModel.swift

class ExampleViewModel 

private let disposeBag = DisposeBag()

private let _textFieldColor: PublishSubject<UIColor>
var textFieldColor: Observable<UIColor>  get  return self._textFieldColor.asObservable()  

init(textFieldObservable: Observable<(Bool, String)>) 
    textFieldObservable.subscribeNext  (focus, text) in
        self.validateTextField(focus, text: text)
    .addDisposableTo(self.disposeBag)


func validateTextField(focus: Bool, text: String) 
    if !focus && !text.isEmpty 
        self._textFieldColor.onNext(UIColor.whiteColor())
     else 
        self._textFieldColor.onNext(UIColor.redColor())
    


(对不起,我不知道如何正确格式化)

基本上我想测试ExampleViewModel 类并通过控制焦点和文本输入来测试它是否发出正确的UIColor

谢谢

【问题讨论】:

【参考方案1】:

感谢我同事的建议,我找到了一种更好的方法来构建 ExampleViewModel 以实现可测试性。通过使用ExampleViewModel 分离验证方法并使用map 运算符设置textFieldColor Observable,其中使用了验证器,验证在外部完成并且不使用Rx,从而简化了逻辑测试.

ExampleViewModel

class ExampleViewModel 

var textFieldColor: Observable<UIColor>

init(
    textFieldText: Observable<String>,
    textFieldFocus: Observable<Bool>,
    validator: TextFieldValidator
) 
    self. textFieldColor = Observable.combineLatest(textFieldText, textFieldFocus)  ($0, $1) . map  validator.validate($1, text: $0) 





 class TextFieldValidator 

func validate(focus: Bool, text: String) -> UIColor 
    if !focus && !text.isEmpty 
        return UIColor.whiteColor()
     else 
        return UIColor.redColor()
    


【讨论】:

以上是关于使用 RxSwift 测试 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章

在 RxSwift 中使用 Stub 提供程序进行注册验证的 XcTest 案例

RxSwift PublishSubject 单元测试

moya 与 RxSwift 使用

在 ViewController 中可观察到的单元测试 RxSwift

在 RxSwift 中测试 UITableView.rx.itemSelected 回调

如何测试 RxSwift 变量和 RxCocoa Observable 之间的 UI 绑定?