【问题标题】:How to test the UI Binding between RxSwift Variable and RxCocoa Observable?如何测试 RxSwift 变量和 RxCocoa Observable 之间的 UI 绑定?
【发布时间】:2018-02-15 17:26:54
【问题描述】:

我有一个简单的ViewModel 有一个属性:

class ViewModel {
    var name = Variable<String>("")
}

我将它绑定到我的ViewController 中的UITextField

class ViewController : UIViewController {

    var viewModel : ViewModel!

    @IBOutlet weak var nameField : UITextField!

    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Binding
        nameField.rx.text
            .orEmpty
            .bind(to: viewModel.name)
            .disposed(by: disposeBag)
    }
}

现在,我想对它进行单元测试。

我可以通过 Rx 使用 .onNext 事件 - nameField.rx.text.onNext("My Name Here") 填充 nameField.text 属性。

但是viewModel.name 没有被填写。为什么?如何使这种 Rx 行为在我的 XCTestCase 中起作用?

请看下面我上次测试运行的结果:

【问题讨论】:

  • UI 组件在尝试进行单元测试时几乎总是会出现问题,这就是它们不适合这项任务的原因。改为测试您的业务逻辑,并让 QA 进行 UI 检查。
  • 好电话@Cristik,我会听取你的建议。我仍然很好奇为什么 Rx 没有被解雇
  • 我推荐使用 RxTest 库和TestScheduler 而不是 GCD。然后,您可以在特定团队安排行动,并且您拥有更多控制权。
  • 另外Variable 已被弃用。您可以使用 BehaviorRelayPublishRelay 作为替代品。

标签: ios swift unit-testing rx-swift rx-cocoa


【解决方案1】:

我相信您遇到的问题是绑定没有明确安排在主线程上。在这种情况下,我建议使用Driver

class ViewModel {
  var name = Variable<String>("")
}

class ViewController: UIViewController {

  let textField = UITextField()
  let disposeBag = DisposeBag()
  let vm = ViewModel()

  override func viewDidLoad() {
    super.viewDidLoad()
    textField.rx.text
        .orEmpty
        .asDriver()
        .drive(vm.name)
        .disposed(by: disposeBag)
}

// ..

使用Driver,绑定将始终发生在主线程上,不会出错。

另外,在你的测试中,我会在绑定上调用skip

sut.nameTextField.rx.text.skip(1).onNext(name)

因为Driver 会在订阅时重播第一个元素。

最后,我建议使用 RxTest 和 TestScheduler 而不是 GCD。

如果这有帮助,请告诉我。

【讨论】:

    【解决方案2】:

    rx.text 依赖于以下 UIControlEvents:.allEditingEvents.valueChanged。因此,显式发送 onNext 事件不会为这些事件发送操作。您应该手动发送操作。

    sut.nameField.rx.text.onNext(name)
    sut.nameField.sendActions(for: .valueChanged)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-04
      • 2018-08-26
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      相关资源
      最近更新 更多