如何使用RxTest测试combineLatest observable?

时间:2017-03-14 14:16:33

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

所以我有这个viewModel,它有一个验证observable,它只是将其他5个信号组合成一个布尔值。

import RxSwift

class SchedulingFormViewModel: BaseViewModel {

    let places = Variable<[String]>([])

    var formIsValid: Observable<Bool>!

    override init() {
        super.init()
        places.value = ["LUGAR 1", "LUGAR 2", "LUGAR 3"]

        formIsValid = Observable.combineLatest(UserSession.currenctScheduling.dateSignal.asObservable(),
                                               UserSession.currenctScheduling.carSignal.asObservable(),
                                               UserSession.currenctScheduling.locationSignal.asObservable(),
                                               UserSession.currenctScheduling.servicesSignal.asObservable())
        { (date: Date?, car: Car?, location: String?, services: [Service]?) in
            print("DATE: \(date), CAR: \(car), LOCATION: \(location), SERVICES:\(services)")
            guard let servicesArray = services else { return false }
            let valid = date != nil && car != nil && location != nil && servicesArray.count > 0
            return valid
        }
    }
}

然后我的测试类有一个方法,只需测试信号是否改变。我尝试了各种方法,但最终都没有真正获得真正的价值。在测试运行后,observable只发出一个真实的信号。

我的测试类设置如下

import XCTest

import RxSwift
import RxTest

@testable import Automobi

class SchedulingUnitTests: XCTestCase {

    var viewModel: SchedulingFormViewModel!
    var disposeBag: DisposeBag!
    var scheduler: TestScheduler!

    override func setUp() {
        super.setUp()
        viewModel = SchedulingFormViewModel()
        UserSession.clearScheduling()
        disposeBag = DisposeBag()
        scheduler = TestScheduler(initialClock: 0) 
    }
}

我已经尝试过TestScheduler

func testFormValidation() {
    UserSession.currenctScheduling.dateSignal.value = Date()
    UserSession.currenctScheduling.carSignal.value = Car()
    UserSession.currenctScheduling.servicesSignal.value = [Service(), Service()]

    let location = scheduler.createHotObservable([
        next(100, "TEST")
    ])

    location.subscribe(onNext: { (text) in
        print("LOCATION: \(text)")
        UserSession.currenctScheduling.locationSignal.value = text
    }).addDisposableTo(disposeBag)


    let results = scheduler.createObserver(Bool.self)

    scheduler.scheduleAt(0) { 
        self.viewModel.formIsValid.subscribe(results).addDisposableTo(self.disposeBag)
    }

    let expected = [
        next(100, true)
    ]

    scheduler.start()

    XCTAssertEqual(results.events, expected)
}

另外

func testFormValidation() {
    UserSession.currenctScheduling.dateSignal.value = Date()
    UserSession.currenctScheduling.carSignal.value = Car()
    UserSession.currenctScheduling.servicesSignal.value = [Service(), Service()]

    let location = scheduler.createHotObservable([
        next(100, "TEST"),
        next(150, "TEST 2"),
        next(200, "TEST 3")
        ])

    location.subscribe(onNext: { (text) in
        print("LOCATION: \(text)")
        UserSession.currenctScheduling.locationSignal.value = text
    }).addDisposableTo(disposeBag)


    var results = [Bool]()
    viewModel.formIsValid.subscribe(onNext: { (value) in
        results.append(value)
    }).addDisposableTo(disposeBag)

    let expected = [true, true, true]

    scheduler.start()

    XCTAssertEqual(results, expected)
}

我尝试过将formIsValid绑定到Variable并在最后验证其值。

func testFormValidation() {
        UserSession.currenctScheduling.dateSignal.value = Date()
        UserSession.currenctScheduling.carSignal.value = Car()
        UserSession.currenctScheduling.locationSignal.value = "TESTE"
        UserSession.currenctScheduling.servicesSignal.value = [Service(), Service()]

        sleep(5)

        XCTAssertTrue(viewModel.formIsValid.value)
}

但我从来没有得到预期的结果。在所有测试失败并且代码返回执行后,我确实得到了一个真实的信号。此外,在运行应用程序时,代码按预期执行,我只需要在测试中捕获它。有什么想法吗?!

1 个答案:

答案 0 :(得分:0)

在您第一次尝试时,您可能会在时钟0上获得一个值,因此您的expected值应为:

let expected = [
    next(0, false)
    next(100, true)
]