RxSwift的调度程序在切换后很奇怪

时间:2019-08-05 02:39:50

标签: rx-swift

我遇到了RxSwift调度程序的问题。

如下所示的生产代码,

class SomePresenter {

    let repository: SomeRepository
    let subscribeScheduler: ImmediateSchedulerType

    var list: [SomeEntity] = []

    let bag = DisposeBag()

    init(repository: SomeRepository,
         subscribeScheduler: ImmediateSchedulerType) {
        self.repository = repository
        self.subscribeScheduler = subscribeScheduler
    }

    func some() {
        repository
            .getSome()
            .subscribeOn(subscribeScheduler)
            .observeOn(MainScheduler.instance)
            .subscribe(onSuccess: { [weak self] list in
                guard let self = self else {
                    return
                }
                self.list = list
            }) { error in
                fatalError()
            }.disposed(by: bag)
    }
}

并为此进行测试,如下所示。

class researchRxTestFailedTests: XCTestCase {

    func testExample1() {
        let presenter1 = SomePresenter(repository: MockedSomeRepository(),
                                      subscribeScheduler: ConcurrentMainScheduler.instance)
        presenter1.some()
        XCTAssertEqual(presenter1.list.count, 2)
    }

    func testExample2() {
        let presenter2 = SomePresenter(repository: MockedSomeRepository(),
                                      subscribeScheduler: ConcurrentMainScheduler.instance)
        presenter2.some()
        XCTAssertEqual(presenter2.list.count, 2)
    }

    func testExample3() {
        let presenter3 = SomePresenter(repository: MockedSomeRepository(),
                                      subscribeScheduler: SerialDispatchQueueScheduler.init(qos: .default)) // Here is key!!
        presenter3.some()
        XCTAssertEqual(presenter3.list.count, 2)
    }

    func testExample4() {
        let presenter4 = SomePresenter(repository: MockedSomeRepository(),
                                      subscribeScheduler: ConcurrentMainScheduler.instance)
        presenter4.some()
        XCTAssertEqual(presenter4.list.count, 2)
    }

    func testExample5() {
        let presenter5 = SomePresenter(repository: MockedSomeRepository(),
                                      subscribeScheduler: ConcurrentMainScheduler.instance)
        presenter5.some()
        XCTAssertEqual(presenter5.list.count, 2)
    }

    class MockedSomeRepository: SomeRepository {
        func getSome() -> Single<[SomeEntity]> {
            return Single.just(
                [
                    SomeEntity(id: 100, name: "hoge"),
                    SomeEntity(id: 101, name: "fuga")
                ]
            )
        }
    }
}

当我运行此测试代码(不是randomize execution order)时,出现如下所示的错误。

enter image description here

那为什么会这样呢? 我知道testExample3失败,因为它的调度程序是后台调度程序。 但是我不明白为什么即使这些调度程序是主线程调度程序,以下测试示例(testExample4testExample5)也会失败。

注意:如果我在ConcurrentMainScheduler中切换到testExample3,则所有测试均通过。

0 个答案:

没有答案