如何测试执行流程/顺序?

How do I test for flow / order of execution?

我正在尝试添加一项功能以向此代码显示加载屏幕:

func connect(with code: String) {
    interactor.connect(with: code)
        .subscribe(onNext: { displaySuccessScreenRelay.accept(()) },
                   onError: { displayErrorScreenRelay.accept(()) } )
        .disposed(by: disposeBag)
}

我制作了一个名为 loadingScreenShownRelay 的行为中继广告,我知道正确的做法是这样的:

func connect(with code: String) {
    loadingScreenShownRelay.accept(true)
    interactor.connect(with: code)
        .subscribe(onNext: { 
                       displaySuccessScreenRelay.accept(())
                       loadingScreenShownRelay.accept(false)
                   },
                   onError: { 
                       displayErrorScreenRelay.accept(()) 
                       loadingScreenShownRelay.accept(false)
        })
        .disposed(by: disposeBag)
}

现在的问题是如何重新安排测试,以便我不仅可以测试逻辑,还可以测试 showLoading -> success -> hideLoading 的顺序?

我可能可以将显示和 loadingScreenShown 可观察对象分别测试为 2 个测试(即,一个用于测试 input-> emit display success / error 的逻辑,另一个用于测试 loadingScreenShown)。但是我怎么知道订单确实是 showLoading -> success -> hideLoading ?如果我在不考虑顺序的情况下进行测试,我也可以这样做并且测试仍然是绿色的。

func connect(with code: String) {
    loadingScreenShownRelay.accept(true)
    loadingScreenShownRelay.accept(false)
    interactor.connect(with: code)
        .subscribe(onNext: { displaySuccessScreenRelay.accept(()) },
                   onError: { displayErrorScreenRelay.accept(()) } )
        .disposed(by: disposeBag)
}

提前致谢。

像您这样的命令式代码可能很难测试。您需要对整个 class 进行测试,并且需要一个假的交互器。

像这样的测试将表明您的加载屏幕中继有效:

class ExampleTests: XCTestCase {

    func test() {
        let scheduler = TestScheduler(initialClock: 0)
        let sut = Example(interactor: FakeInteractor(connect: { _ in
            scheduler.createColdObservable([.next(10, ()), .completed(10)]).asObservable()
        }))
        let result = scheduler.createObserver(Bool.self)

        _ = sut.loadingScreenShownRelay
            .bind(to: result)

        sut.connect(with: "foo")

        scheduler.start()

        XCTAssertEqual(result.events, [.next(0, true), .next(10, false)])
    }
}

您可以在断言中看到 true 事件出现在 false 事件之前,并且它们由交互器发出所需的时间单位分隔。

以上使用了RxTest库。