【问题标题】:Flutter - Mockito Firestore...get() - The method 'document' was called on nullFlutter - Mockito Firestore ...get() - 方法'document'在null上被调用
【发布时间】:2020-02-27 15:09:18
【问题描述】:

出于学习目的,我正在尝试使用 Mockito 模拟 Firestore 控制器类。

firestore_controller.dart

import 'package:cloud_firestore/cloud_firestore.dart';


class FirestoreController implements FirestoreControllerInterface {

  final Firestore firestoreApi;
  FirestoreController({this.firestoreApi});

  @override
  Future<DocumentSnapshot> read() async {
    final DocumentSnapshot document = await this.firestoreApi.collection('user').document('user_fooBar').get();
    return document;
  }
}

firestore_controller_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mockito/mockito.dart';
import 'package:fooApp/Core/repositories/firebase/firestore_controller.dart';

class MockFirestoreBackend extends Mock implements Firestore {}
class MockDocumentSnapshot extends Mock implements DocumentSnapshot {}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group("Firebase Controller", () {

    final Firestore firestoreMock = MockFirestoreBackend();
    final MockDocumentSnapshot mockDocumentSnapshot = MockDocumentSnapshot();
    FirestoreController sut;

    test("try to read a document", () async {

      // Arrange
      final Map<String, dynamic> _fakeResponse = {
        'foo': 123,
        'bar': 'foobar was here',
      };

      sut = FirestoreController(firestoreApi: firestoreMock); // INJECT MOCK

      // Arrange: Mock
      when(firestoreMock.collection('user').document('user_fooBar').get()).thenAnswer((_) => Future<MockDocumentSnapshot>.value(mockDocumentSnapshot));
      when(mockDocumentSnapshot.data).thenReturn(_fakeResponse);

      // Act
      final fakeDocument = await sut.read();

    });
  });
}

???? 控制台输出 ????

NoSuchMethodError: The method 'document' was called on null.
Receiver: null
Tried calling: document("user_fooBar")

对不起,如果错误很明显,这是我第一次使用 Mockito 我的错误在哪里?我想念什么?非常感谢!

【问题讨论】:

  • 如果是Java之类的东西,我相信你必须安排firestoreMock在你调用DocumentReference时返回一个模拟的collection(),否则该方法将默认返回null .在你告诉它做什么之前,Mockito 不知道如何处理模拟对象上的任何方法。
  • 我也有同样的问题。

标签: firebase flutter dart google-cloud-firestore mockito


【解决方案1】:

试试这个:

https://pub.dev/packages/cloud_firestore_mocks

我使用它完成的测试:

class MockFirestore extends Mock implements Firestore {}
class MockDocument extends Mock implements DocumentSnapshot {}

void main() {
  final _tAppointmentModel = AppointmentModel(
    appointmentID: kAppointmentID,
    date: DateTime.parse("2020-12-05 20:18:04Z"),
    description: "test description",
    doctorID: kDoctorID,
    hospitalID: kHospitalID,
    infantID: kInfantID,
  );

  group('AppointmentModel tests: ', () {
    final tAppointmentID = kAppointmentID;
    final tInfantID = kInfantID;
    final tDoctorID = kDoctorID;
    final tHospitalID = kHospitalID;

    test('should be a subclass of Appointment', () async {
      expect(_tAppointmentModel, isA<Appointment>());
    });

    test('store and retrieve document from Firestore', () async {
      final instance = MockFirestoreInstance();
      await instance.collection('appointments').add({
        'appointmentID': tAppointmentID,
        'date': DateTime.parse("2020-12-05 20:18:04Z"),
        'description': "test description",
        'doctorID': tDoctorID,
        'hospitalID': tHospitalID,
        'infantID': tInfantID,
      });

      final snapshot = await instance.collection('appointments').getDocuments();
      final String expected = _tAppointmentModel.props[0];
      final String result = snapshot.documents[0].data['appointmentID'];
      expect(expected, result);
    });
  });
}

【讨论】:

    【解决方案2】:

    所以我想我已经找到了原因 - 它似乎是 Mockito 中的一个错误(ette),因为它不处理从 collection(any) 到 document() 或 getDocuments( )。我是这样修复的:

    声明五个类:

    class MockFirebaseClient extends Mock implements Firestore {} //for your mock injection
    
    class MockCollectionReference extends Mock implements CollectionReference {} //for when declaration
    
    class MockQuerySnapshot extends Mock implements QuerySnapshot {} //for the thenAnswer return on collection of docs
    
    class MockDocumentReference extends Mock implements DocumentReference {} //for single doc query
    
    class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} // for the thenAnswer return on single doc query
    

    做你的设置等等 - 那么 when 子句就是:

    when(mockCollectionReference.getDocuments())
             .thenAnswer((_) => Future.value(mockQuerySnapshot));  //for collection of docs query
    
    when(mockDocumentReference.get())
                .thenAnswer((_) => Future.value(mockDocumentSnapshot)); //for single doc query 
    

    【讨论】:

      猜你喜欢
      • 2019-03-10
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 2020-04-09
      • 2020-06-12
      • 2020-06-07
      • 2020-01-22
      相关资源
      最近更新 更多