如何用RxTest测试API错误响应并获取错误中的响应值
问题
我想用RxTest测试API返回的错误,但不知道如何从错误中获取响应值。业务代码实现如下:
func submitForm() { guard let denom = selectedDenom, let bal = accountBalance else { return } eventShowHideLoadingIndicator.onNext(true) manageCash.submitForm(cashType: cashType, denom: denom, accountBalance: bal) .subscribe(onFailure: { error in self.eventShowHideLoadingIndicator.onNext(false) guard let grpcError = error as? ErrorParser, grpcError.type() == .NeedAuthorization, !grpcError.authRequestId.isEmpty else { self.errorHandler(error: error) return } self.eventPinRequired.onNext(grpcError.authRequestId) }).disposed(by: disposeBag) }
我目前编写的测试代码如下,但测试失败,原因是无法从错误中获取所需值:
describe("submitForm") { beforeEach { mockManageCash.submitFormCashTypeDenomAccountBalanceReturnValue = Single.error(ErrorParser(grpcError: .NeedAuthorization)) } context("when submit form return error") { it("should return error NeedAuthorization") { // Given viewModel.selectedDenom = mockCashInquiryDenom viewModel.accountBalance = mockAccountBalance let observer = scheduler.createObserver(String.self) viewModel.rxEventPinRequired.subscribe(observer).disposed(by: disposedBag) // When viewModel.submitForm() // Then expect(observer.events.count).to(equal(1)) } } }
解决方案
测试失败的核心原因是你构造ErrorParser实例时没有传入非空的authRequestId,业务代码里的判断条件!grpcError.authRequestId.isEmpty会拦截空值,导致eventPinRequired不会发送事件,观察者自然收不到数据。
修复步骤:
构造带有效
authRequestId的ErrorParser
修改测试中的beforeEach代码,确保创建ErrorParser时传入非空的authRequestId(假设ErrorParser支持该参数初始化,若原构造函数无此参数,需调整构造逻辑或在实例创建后设置该属性):beforeEach { mockManageCash.submitFormCashTypeDenomAccountBalanceReturnValue = Single.error( ErrorParser(grpcError: .NeedAuthorization, authRequestId: "test-auth-001") ) }增强断言的准确性
除了断言事件数量,还可以验证返回的authRequestId是否符合预期,让测试更严谨:// Then expect(observer.events.count).to(equal(1)) expect(observer.events.first?.element).to(equal("test-auth-001"))可选:验证加载状态的完整流程
如果需要覆盖更多业务逻辑,可以同时监听加载状态的变化,确保其从显示变为隐藏:// Given let loadingObserver = scheduler.createObserver(Bool.self) viewModel.eventShowHideLoadingIndicator.subscribe(loadingObserver).disposed(by: disposedBag) // Then expect(loadingObserver.events).to(equal([ .next(0, true), .next(0, false) ]))
内容的提问来源于stack exchange,提问作者ferryawijayanto
相关产品推荐
相关产品推荐

