StateNotifierProvider单元测试未捕获初始加载状态问题求助
StateNotifierProvider单元测试未捕获初始加载状态问题求助
我最近在给StateNotifierProvider写单元测试的时候碰到个奇怪的问题:测试失败场景时,单元测试没能捕获到初始的加载状态。Test A和Test B都正常跑通,但Test C就出问题了,想请教下大家这是怎么回事。
先贴一下我的Provider实现代码:
final paymentBundleVM = StateNotifierProvider.autoDispose<PaymentBundleVM, PaymentBundleState>( (ref) => PaymentBundleVM(ref.read(getPaymentBundleUseCase), ref.read(createPaymentBundleUseCase)), dependencies: [getPaymentBundleUseCase, createPaymentBundleUseCase], name: 'paymentBundleVM', ); class PaymentBundleVM extends StateNotifier<PaymentBundleState> { PaymentBundleVM(this._getBundleUseCase, this._createBundleUseCase) : super(PaymentBundleLoading()) { unawaited(_loadDependencies()); } final GetPaymentBundleUseCase _getBundleUseCase; final CreatePaymentBundleUseCase _createBundleUseCase; Future<void> _loadDependencies() async { try { final bundle = await _getBundleUseCase.run(); if (mounted) { if (bundle != null) state = PaymentBundleLoaded(bundle); else state = PaymentBundleDisabled(); } } on BaseException catch (exception) { if (mounted) state = PaymentBundleFailedLoadingState(exception); } } } abstract class PaymentBundleState extends Equatable { @override List<Object?> get props => []; } class PaymentBundleLoading extends PaymentBundleState {} class PaymentBundleDisabled extends PaymentBundleState {} class PaymentBundleLoaded extends PaymentBundleState { PaymentBundleLoaded(this.bundle); final PaymentBundle bundle; @override List<Object?> get props => [...super.props, bundle]; } class PaymentBundleFailedLoadingState extends PaymentBundleState { PaymentBundleFailedLoadingState(this.exception); final BaseException exception; @override List<Object?> get props => [...super.props, exception]; }
然后是我的单元测试代码:
void main() { final getPaymentBundleUseCaseMock = GetPaymentBundleUseCaseMock(); final createPaymentBundleUseCaseMock = CreatePaymentBundleUseCaseMock(); late ProviderContainer container; final fakeBundle = PaymentBundleMock(); setUp(() { container = ProviderContainer( overrides: [ getPaymentBundleUseCase.overrideWith((ref) => getPaymentBundleUseCaseMock), createPaymentBundleUseCase.overrideWith((ref) => createPaymentBundleUseCaseMock), ], ); }); tearDown(() { reset(getPaymentBundleUseCaseMock); reset(createPaymentBundleUseCaseMock); }); test('test A', () async { when(getPaymentBundleUseCaseMock.run).thenAnswer((_) => Future.value(fakeBundle)); final listener = ListenerMock<PaymentBundleState>(); container.listen<PaymentBundleState>(paymentBundleVM, listener, fireImmediately: true); await container.pump(); verifyInOrder( [ () => listener(null, PaymentBundleLoading()), () => listener(PaymentBundleLoading(), PaymentBundleLoaded(fakeBundle)), ], ); verifyNoMoreInteractions(listener); }); test('test B', () async { when(getPaymentBundleUseCaseMock.run).thenAnswer((_) => Future.value()); final listener = ListenerMock<PaymentBundleState>(); container.listen<PaymentBundleState>(paymentBundleVM, listener, fireImmediately: true); await container.pump(); verifyInOrder( [ () => listener(null, PaymentBundleLoading()), () => listener(PaymentBundleLoading(), PaymentBundleDisabled()), ], ); verifyNoMoreInteractions(listener); }); test('test C', () async { final exception = HttpException.handshake(); when(getPaymentBundleUseCaseMock.run).thenThrow(exception); final listener = ListenerMock<PaymentBundleState>(); container.listen<PaymentBundleState>(paymentBundleVM, listener, fireImmediately: true); await container.pump(); verifyInOrder( [ () => listener(null, PaymentBundleLoading()), () => listener(PaymentBundleLoading(), PaymentBundleFailedLoadingState(exception)), ], ); verifyNoMoreInteractions(listener); }); }
现在的问题是,Test A和Test B都符合预期,但Test C抛出了错误:
Matching call #0 not found. All calls: ListenerMock
.call(
null,
PaymentBundleFailedLoadingState( [BaseException - handshakeHttp] null.
Server message: null
User message: null
statusCode: null
))
简单说就是Test C里,测试认为状态直接从null跳到了PaymentBundleFailedLoadingState,完全没捕获到PaymentBundleLoading这个初始状态。按我的理解,状态流程应该是null -> loading -> failedLoading才对,为什么加载状态没被识别到呢?有没有大佬能帮忙分析下原因?
备注:内容来源于stack exchange,提问作者GGirotto
相关产品推荐
相关产品推荐

