flutter 中的 Bloc 测试问题

问题描述 投票:0回答:1

想要测试这个 bloc 方法,使用冻结的 bloc 架构。

FutureOr<void> _debitAmount(
    _DebitAmount event,
    Emitter<FeePaymentState> emit,
  ) async {
    try {
      emit(state.copyWith(isBusy: true));

      final debitAmountResponseModel =
          await _repository.debitAmount(event.body);

      VerifyServiceFeeRequestModel verifyServiceFeeRequestModel =
          VerifyServiceFeeRequestModel(
        transactionId: num.parse(event.body.moduleTransactionId!),
        amount: event.body.amount!,
        walletTxnId:
            num.parse(debitAmountResponseModel.data!.walletTransactionId!),
        moduleId: 12,
        recordType: event.body.recordType,
        paymentReceiptNo: event.body.receiptNo,
      );

      final verifyService =
          await _repository.verifyService(verifyServiceFeeRequestModel);

      emit(
        state.copyWith(
            isBusy: false,
            debitAmountResponseModel: debitAmountResponseModel,
            verifyServiceFeeResponseModel: verifyService,
            notification: _NotifySuccess(message: 'debitAmountResponseModel'),
            status: const UILoadSuccess()),
      );
    } catch (e, s) {
      _log.e('Load failed', e, s);
      emit(
        state.copyWith(
          isBusy: false,
          notification: _NotifyFailed(
            message:
                e is DioException ? e.response!.data['message'] : e.toString(),
          ),
        ),
      );
    }
  }

单元测试用例

 group('_DebitAmount', () {
    const response = DebitAmountResponseModel();
    const verifyResponse = VerifyServiceFeeResponseModel();
    const body = DebitAmountRequestModel();
    VerifyServiceFeeRequestModel verifyServiceFeeRequestModel =
        const VerifyServiceFeeRequestModel();

    blocTest<FeePaymentBloc, FeePaymentState>(
      '_DebitAmount successful',
      build: () => feePaymentBloc,
      setUp: () {
        when(mockFeePaymentRepository.debitAmount(body)).thenAnswer(
          (_) => Future<DebitAmountResponseModel>.value(response),
        );
        when(mockFeePaymentRepository
                .verifyService(verifyServiceFeeRequestModel))
            .thenAnswer(
          (_) => Future<VerifyServiceFeeResponseModel>.value(verifyResponse),
        );
      },
      act: (bloc) async {
        bloc.add(const FeePaymentEvent.debitAmount(body));
      },
      expect: () => [
        isA<FeePaymentState>().having(
          (state) => state.isBusy,
          'isBusy',
          true,
        ),
        isA<FeePaymentState>()
            .having(
              (state) => state.isBusy,
              'isBusy',
              false,
            )
            .having(
              (state) => state.debitAmountResponseModel,
              'debitAmountResponseModel',
              response,
            )
            .having(
              (state) => state.verifyServiceFeeResponseModel,
              'verifyServiceFeeResponseModel',
              verifyResponse,
            )
            .having(
              (state) => state.status,
              'status',
              const UILoadSuccess(),
            ),
      ],
    );

}

不明白如何读取此错误

Expected: [
            <<Instance of 'FeePaymentState'> with `isBusy`: <true>>,
            <<Instance of 'FeePaymentState'> with `isBusy`: <false> and `debitAmountResponseModel`: _$DebitAmountResponseModelImpl:<DebitAmountResponseModel(status: null, success: null, count: null, data: null, type: null)> and `verifyServiceFeeResponseModel`: _$VerifyServiceFeeResponseModelImpl:<VerifyServiceFeeResponseModel(status: null, success: null, count: null, data: null, type: null)> and `status`: _$UILoadSuccessImpl:<UIStatus.loadSuccess(message: null)>>
          ]
  Actual: [
            _$FeePaymentStateImpl:FeePaymentState(status: UIStatus.initial(), notification: null, isBusy: true, isNavigated: false, walletInfoResponseModel: null, walletBalanceResponseModel: null, debitAmountResponseModel: null, verifyServiceFeeResponseModel: null),
            _$FeePaymentStateImpl:FeePaymentState(status: UIStatus.initial(), notification: FeePaymentNotification.notifyFailed(message: Null check operator used on a null value), isBusy: false, isNavigated: false, walletInfoResponseModel: null, walletBalanceResponseModel: null, debitAmountResponseModel: null, verifyServiceFeeResponseModel: null)
          ]
   Which: at location [1] is _$FeePaymentStateImpl:<FeePaymentState(status: UIStatus.initial(), notification: FeePaymentNotification.notifyFailed(message: Null check operator used on a null value), isBusy: false, isNavigated: false, walletInfoResponseModel: null, walletBalanceResponseModel: null, debitAmountResponseModel: null, verifyServiceFeeResponseModel: null)> which has `debitAmountResponseModel` with value <null>
flutter unit-testing bloc-test
1个回答
0
投票

预期状态: 第一个状态预计将 isBusy 设置为 true。 第二个状态预计将具有: isBusy 设置为 false。 debitAmountResponseModel 设置为 DebitAmountResponseModel 的实例。 verifyServiceFeeResponseModel 设置为VerifyServiceFeeResponseModel 的实例。 状态设置为 UILoadSuccess 的实例。

实际状态: bloc 返回的第一个状态将 isBusy 设置为 true,这与预期相符。 该集团返回的第二个状态有: isBusy 设置为 false,符合预期。 然而,实际状态下的 debitAmountResponseModel 为 null,这与预期状态不匹配,它应该是 DebitAmountResponseModel 的实例。

错误原因: 该错误表明第二个状态下的 debitAmountResponseModel 为 null,而它应该是 DebitAmountResponseModel 的实例。

可能的解决方案: 检查实现:确保 _DebitAmount 函数的实现正确返回具有预期值的 debitAmountResponseModel。验证 debitAmountResponseModel 是否在 _repository.debitAmount 调用中正确设置。

检查模拟:确保测试中 debitAmount 的模拟设置返回预期的 DebitAmountResponseModel。仔细检查when(mockFeePaymentRepository.debitAmount(body)).thenAnswer(...)的实现。

检查依赖关系:确保在测试环境中正确提供并初始化构建 debitAmountResponseModel 所需的所有依赖关系。

调试:如有必要,在测试或块实现中添加日志记录或调试语句,以了解数据流并识别设置 debitAmountResponseModel 时的任何潜在问题。

通过执行这些步骤,您应该能够查明并解决测试用例中预期状态与实际状态之间的差异。

© www.soinside.com 2019 - 2024. All rights reserved.