你如何测试一个可观察对象在失败时是否重试了 X 次?

How do you test if an observable is retried X times when failing?

我有一个 observable,如果它失败了,我需要重试几次。我目前正在尝试对其进行单元测试。到目前为止,我已经这样做了,但它失败了,总是返回 1 次而不是 11 次:

func testSetCreated_ShouldRetry10Times_BeforeStopping() throws {
    let setCreatedProvider: (String, String) -> Single<ResponseData> = { (_, _) in
        return .error(RxCocoaURLError.unknown)
    }
    let statusHandler = createConsultationHandler(setCreatedProvider: setCreatedProvider)

    var setCreatedEmitCount = 0
    statusHandler.setCreated(consultationId: .random(length: 24))
        .subscribe(onError: { _ in
            setCreatedEmitCount += 1
        })
        .disposed(by: disposeBag)

    sleep(10)
    XCTAssertEqual(11, setCreatedEmitCount)
}

那么,如果失败,我该如何测试它最多被调用 11 次?谢谢

首先,了解 Observable 只会发出 单个 错误事件。没有办法让您的测试按原样通过。

但是,尽管我不确定为什么在检查它是否进行了 11 次尝试时将函数命名为 10Times,但以下内容将通过。

class rx_sandboxTests: XCTestCase {

    var disposeBag = DisposeBag()

    func testSetCreated_ShouldRetry10Times_BeforeStopping() throws {
        var setCreatedEmitCount = 0
        let setCreatedProvider: (String, String) -> Single<ResponseData> = { (_, _) in
            setCreatedEmitCount += 1
            return .error(RxCocoaURLError.unknown)
        }
        let statusHandler = createConsultationHandler(setCreatedProvider: setCreatedProvider)

        statusHandler.setCreated(consultationId: .random(length: 24))
            .subscribe()
            .disposed(by: disposeBag)

        XCTAssertEqual(11, setCreatedEmitCount)
    }
}

func createConsultationHandler(setCreatedProvider: @escaping (String, String) -> Single<ResponseData>) -> ConsultationHandler {
    return ConsultationHandler(setCreatedProvider: setCreatedProvider)
}

struct ConsultationHandler {
    private let createdProvider: (String, String) -> Single<ResponseData>
    init(setCreatedProvider: @escaping (String, String) -> Single<ResponseData>) {
        self.createdProvider = setCreatedProvider
    }
    func setCreated(consultationId: String) -> Observable<ResponseData> {
        return Observable.just(())
            .flatMap { [createdProvider] in createdProvider("hello", "world") }
            .retry(11)
    }
}
struct ResponseData { }
enum RxCocoaURLError: Error { case unknown }
extension String {
    static func random(length: Int) -> String {
        return ""
    }
}