flutter mockito:如何调用存储库函数进行测试

Posted

技术标签:

【中文标题】flutter mockito:如何调用存储库函数进行测试【英文标题】:flutter mockito: How to call repository function for testing 【发布时间】:2021-11-11 02:01:01 【问题描述】:

开发中没有问题。此问题正在测试中。

备选方案 1

void main() async 
    SoldRepository repository;
  FirebaseFirestore _firestore;

  final sold = Sold(
      buyerDisplayName: UserDisplayNameSold("Saugat Thapa"),
      buyerEmail: EmailAddressBought("saugat26@gmail.com", true),
      buyerPhotoUrl: UserPhotoUrlSold(
          " https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg"),
      buyerUserId: UserIdSold("haSW0s5MxOOENWnc5T1cLinekj2"),
      id: UniqueId(),
      quotations: List3Sold(KtList.of(
        Quotation(
            id: UniqueId(),
            measuremntUnit: QuotationUnit("Kilogram"),
            quantity: QuotationQuantity(10),
            rate: QuotationRate(12),
            title: QuotationTitle("Onion"),
            index: QuotationIndex(8),
            isSelected: QuotationSelected(false)),
      )),
      sellerDisplayName: UserDisplayNameSold("riwat rai"),
      sellerEmail: EmailAddressSold("riwatj@gmail.com"),
      sellerPhotoUrl: UserPhotoUrlSold(
          " https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg"),
      sellerUserId: UserIdSold("DULkECyxWzfBosXXBbOMpfnij1"),
      total: SoldTotalHere(10));
  // User sellerUserDetail;
  final auth = MockFirebaseAuth();
  final googleSignIn = MockGoogleSignIn();
  u.User sellerUserDetail;
  sellerUserDetail = u.User(
      email: "ku1438693@gmail.com",
      photoUrl:
          "https://lh6.googleusercontent.com/-5HXS8qkwKnw/AAAAAAAAAAI/AAAAAAAAAAA/AAKWJJMiRHRadk3nDhlaLa-sU0_fsPrHhQ/photo.jpg",
      id: UniqueId(),
      displayName: "Lila Kunwar");
  setUp(() async 
    repository = SoldRepository(_firestore);
   
  );
  

  test('creates bill in collection sold', () async 
    //arrange
   
    //act

    repository.createTest(sold, sellerUserDetail);
    // assert
    expect(result, right(sold));
  );

调用 repository.createTest(sold, sellerUserDetail) 并出现错误。 我预计FirebaseFirestore _firestore; 会出现问题,但我该如何克服这个问题。

abstract class ISoldRepository 
  
  Future<Either<SoldFailure, Unit>> createTest(
      Sold sold, User sellerUserDetail);
  

/* import 'dart:ui';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:mobile_shamagri_bloc/domain/core/value_objects.dart'; */

import 'dart:developer';

import 'package:cloud_firestore/cloud_firestore.dart';
// import 'package:flutter/services.dart';
import 'package:injectable/injectable.dart';
import 'package:dartz/dartz.dart';
import 'package:kt_dart/kt.dart';
import 'package:logger/logger.dart';
import 'package:mobile_shamagri_bloc/domain/auth/i_auth_facade.dart';
import 'package:mobile_shamagri_bloc/domain/auth/user.dart';
import 'package:mobile_shamagri_bloc/domain/core/errors.dart';
import 'package:mobile_shamagri_bloc/domain/sold/i_sold_repository.dart';
import 'package:mobile_shamagri_bloc/domain/sold/sold_failure.dart';
import 'package:mobile_shamagri_bloc/domain/sold/sold.dart';
import 'package:mobile_shamagri_bloc/domain/sold_not_form/sold_not_form.dart';
import 'package:mobile_shamagri_bloc/domain/sold_not_form/sold_not_form_failure.dart';
import 'package:mobile_shamagri_bloc/infrastructure/core/firestore_helpers.dart';
import 'package:mobile_shamagri_bloc/infrastructure/sold_reso/sold_dtos.dart';
import 'package:mobile_shamagri_bloc/injection.dart';
// import 'package:mobile_shamagri_bloc/infrastructure/sold_reso/sold_dtos.dart';
import 'package:rxdart/rxdart.dart';

@LazySingleton(as: ISoldRepository)
class SoldRepository implements ISoldRepository 
  final FirebaseFirestore _firestore;

  SoldRepository(this._firestore);
  String buyerUserID;
  String buyerDisplayName;
  String buyerPhotoUrl;

  
  Future<Either<SoldFailure, Unit>> createTest(
      Sold sold, User sellerUserDetail) async 
    try 
      final soldDto = SoldDto.fromDomain(
          sold,
          sellerUserDetail,
          sold.buyerUserId.getOrCrash(),
          sold.buyerDisplayName.getOrCrash(),
          sold.buyerPhotoUrl.getOrCrash());

      await _firestore
          .collection("sold")// here is the error
          .doc(soldDto.soldId)
          .collection("invoice")
          .doc()
          .set(soldDto.toJson());

      return right(unit);
     on FirebaseException catch (e) 
      if (e.message.contains('PERMISSION_DENIED')) 
        return left(const SoldFailure.insufficientPermission());
       else 
        var logger = Logger();
        logger.wtf("unexpected error " + e.toString());
        return left(const SoldFailure.unexpected());
      
    
  
  



我怎么不能在 null 上调用方法 'collection'?

creates bill in collection sold [E]
  NoSuchMethodError: The method 'collection' was called on null.
  Receiver: null
  Tried calling: collection("sold")
  dart:core                                                                          Object.noSuchMethod
  package:mobile_shamagri_bloc/infrastructure/sold_reso/sold_repository.dart 228:12  SoldRepository.createTest
  test\features\sold\presentation\bloc\create.dart 85:21                             main.<fn>
  test\features\sold\presentation\bloc\create.dart 83:43                             main.<fn>
  ===== asynchronous gap ===========================
  dart:async                                                                         _completeOnAsyncError
  package:mobile_shamagri_bloc/infrastructure/sold_reso/sold_repository.dart         SoldRepository.createTest
  test\features\sold\presentation\bloc\create.dart 85:21                             main.<fn>
  test\features\sold\presentation\bloc\create.dart 83:43                             main.<fn>

  NoSuchMethodError: The method 'collection' was called on null.
  Receiver: null
  Tried calling: collection("sold")
  dart:core                                                                          Object.noSuchMethod
  package:mobile_shamagri_bloc/infrastructure/sold_reso/sold_repository.dart 228:12  SoldRepository.createTest
  test\features\sold\presentation\bloc\create.dart 88:31                             main.<fn>
  test\features\sold\presentation\bloc\create.dart 83:43                             main.<fn>
  ===== asynchronous gap ===========================
  dart:async                                                                         _completeOnAsyncError
  package:mobile_shamagri_bloc/infrastructure/sold_reso/sold_repository.dart         SoldRepository.createTest
  test\features\sold\presentation\bloc\create.dart 88:31                             main.<fn>
  test\features\sold\presentation\bloc\create.dart 83:43                             main.<fn>

  Expected: Right<dynamic, Sold>:<Right(Sold(id: Value(Right(6f567c00-16a0-11ec-b349-256f5961cbea)), total: Value(Right(10)), buyerEmail: Value(Right(saugat26@gmail.com)), quotations: Value(Right([Quotation(id: Value(Right(6f56ca20-16a0-11ec-8c22-5db758776962)), title: Value(Right(Onion)), measuremntUnit: Value(Right(Kilogram)), rate: Value(Right(12)), quantity: Value(Right(10)), isSelected: Value(Right(false)), index: Value(Right(8)))])), sellerEmail: Value(Right(rrj@gmail.com)), sellerUserId: Value(Right(DULkEuiCyzfBosXXBbOMpfnij1)), buyerUserId: Value(Right(hanSW0s5MxOONWnc5T1cLinekj2)), sellerDisplayName: Value(Right(riwat rai)), buyerDisplayName: Value(Right(Saugat Thapa)), sellerPhotoUrl: Value(Right( https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg)), buyerPhotoUrl: Value(Right( https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg))))>
    Actual: <Instance of 'Future<Either<SoldFailure, Unit>>'>

  package:test_api                                        expect
  package:flutter_test/src/widget_tester.dart 428:3       expect
  test\features\sold\presentation\bloc\create.dart 90:5   main.<fn>
  test\features\sold\presentation\bloc\create.dart 83:43  main.<fn>

备选方案 2

void main() async 
    SoldRepository repository;
  FirebaseFirestore _firestore;

  final sold = Sold(
      buyerDisplayName: UserDisplayNameSold("Saugat Thapa"),
      buyerEmail: EmailAddressBought("saugat26@gmail.com", true),
      buyerPhotoUrl: UserPhotoUrlSold(
          " https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg"),
      buyerUserId: UserIdSold("hanSW0s5MxOOENWnc5T1cLinekj2"),
      id: UniqueId(),
      quotations: List3Sold(KtList.of(
        Quotation(
            id: UniqueId(),
            measuremntUnit: QuotationUnit("Kilogram"),
            quantity: QuotationQuantity(10),
            rate: QuotationRate(12),
            title: QuotationTitle("Onion"),
            index: QuotationIndex(8),
            isSelected: QuotationSelected(false)),
      )),
      sellerDisplayName: UserDisplayNameSold("riwat rai"),
      sellerEmail: EmailAddressSold("riwatj@gmail.com"),
      sellerPhotoUrl: UserPhotoUrlSold(
          " https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg"),
      sellerUserId: UserIdSold("DULkEuiCyxWzfBosXXBbOMpfnij1"),
      total: SoldTotalHere(10));
  // User sellerUserDetail;
  final auth = MockFirebaseAuth();
  final googleSignIn = MockGoogleSignIn();
  u.User sellerUserDetail;
  sellerUserDetail = u.User(
      email: "ku143863@gmail.com",
      photoUrl:
          "https://lh6.googleusercontent.com/-5HXS8qkwKnw/AAAAAAAAAAI/AAAAAAAAAAA/AAKWJJMiRHRadk3nDhlaLa-sU0_fsPrHhQ/photo.jpg",
      id: UniqueId(),
      displayName: "Lila Kunwar");
  setUp(() async 
    repository = SoldRepository(_firestore);
   
  );
  

  test('creates bill in collection sold', () async 
    //arrange
   
    //act

   ISoldRepository repository;
    final globalResult = repository.createTest(sold, sellerUserDetail);
    expect(globalResult, d.right(sold));
  );

00:02 +0 -1: creates bill in collection sold [E]
  NoSuchMethodError: The method 'createTest' was called on null.
  Receiver: null
  Tried calling: createTest(Instance of '_$_Sold', Instance of '_$_User')
  dart:core                                               Object.noSuchMethod
  test\features\sold\presentation\bloc\create.dart 88:37  main.<fn>
  test\features\sold\presentation\bloc\create.dart 83:43  main.<fn>

【问题讨论】:

【参考方案1】:

Alternative 1 中,您在 null 上调用 .collection,因为 _firestore 变量只是声明了但没有赋值。

Alternative 2 中,您在null 上调用.createTest,因为调用.createTestrepository 变量是在下面的test 方法中声明的变量,并且它为null,因为它没有被分配任何值。

test('creates bill in collection sold', () async 
    ISoldRepository repository;
    final globalResult = repository.createTest(sold, sellerUserDetail);
    expect(globalResult, d.right(sold));
);

您可以使用 mockito 模拟 FirebaseFirestore 并将其分配给您的 _firestore 变量。查看article,了解如何使用 Firestore 编写单元测试。

【讨论】:

以上是关于flutter mockito:如何调用存储库函数进行测试的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Mockito 测试模拟失败

使用 Mockito 的 FutureBuilder 快照数据为空 - Flutter

用 Mockito Flutter 模拟 Hive

如何使用 Mockito 验证带有 ByteBuffer 参数的调用?

如何使用 mockito 测试空值?

如何测试 Json.parser 不是用 mockito java 调用的?