Home > database >  Flutter unit testing firestore
Flutter unit testing firestore

Time:03-07

I'm new to unit testing in general. I'm trying to test simple method from my DataRepository.

Following this link but seems deprecated: https://utkarshkore.medium.com/writing-unit-tests-in-flutter-with-firebase-firestore-72f99be85737

Stream<List<Note>> noteStream() {
        try {
          return collection.snapshots().map((notes) {
            final List<Note> notesFromFirestore = <Note>[];
            for (var doc in notes.docs) {
              notesFromFirestore.add(Note.fromSnapshot(doc));
            }
            return notesFromFirestore;
          });
        } catch (e) {
          rethrow;
        }
      }

So far this is what my test file look like:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

class MockFirestore extends Mock implements FirebaseFirestore {}
class MockCollectionReference extends Mock implements CollectionReference {}

void main() {
  MockFirestore instance = MockFirestore();
  MockCollectionReference mockCollectionReference = MockCollectionReference();

  test('should return data when the call to remote source is succesful.',
      () async {
    when(instance.collection('notes')).thenReturn(mockCollectionReference);
  });
}

First instance throw me this error

The argument type 'MockCollectionReference' can't be assigned to the parameter type 'CollectionReference<Map<String, dynamic>>'

I would really appreciate the help for testing the method.

CodePudding user response:

This should solve your problem: Specify a type for CollectionReference. This way:

class MockCollectionReference extends Mock implements CollectionReference<Map<String, dynamic>> {}

CodePudding user response:

You can use the fake_cloud_firestore to mock the Firestore instance by using it's FakeCloudFirestore object that can be used in the place of an actual FirebaseFirestore object.

An Example:

 import 'package:cloud_firestore/cloud_firestore.dart';
 import 'package:fake_cloud_firestore/fake_cloud_firestore.dart';

 test('noteStream returns Stream containing List of Note objects', () async {
      //Define parameters and objects

      final FakeFirebaseFirestore fakeFirebaseFirestore = FakeFirebaseFirestore();

      final DataRepository dataRepository =
          DataRepository(firestore: fakeFirebaseFirestore);

      final CollectionReference mockCollectionReference =
          fakeFirebaseFirestore.collection(dataRepository.collection.path);

      final List<Note> mockNoteList = [Note()];

      // Add data to mock Firestore collection
      for (Note mockNote in mockNoteList) {
        await mockCollectionReference.add(mockNote.toSnapshot());
      }

      // Get data from DataRepository's noteStream i.e the method being tested
      final Stream<List<Note>> noteStreamFromRepository =
          dataRepository.noteStream();

      final List<Note> actualNoteList = await noteStreamFromRepository.first;

      final List<Note> expectedNoteList = mockNoteList;

      // Assert that the actual data matches the expected data
      expect(actualNoteList, expectedNoteList);
    });

Explanation:

The test above makes the following assumptions about your code:

  • You pass the FirebaseFirestore object into the DataRepository object.
  • You have a toSnapshot method on your Note object which converts your Note object into a Map<String, dynamic> object.

The test works into the following way:

  1. It creates the necessary objects needed for the test i.e the FakeFirebaseFirestore object, the DataRepository object, the mock CollectionReference object and the mock data to be passed into the mock collection reference (mockNoteList).
  2. It adds the data into the mock collection reference.
  3. It gets the data using the DataRepository's noteStream method.
  4. It asserts that the actual data from the DataRepository is equal to the expected data i.e the data passed originally into the mock collection reference.

Resources:

For more understanding on unit testing Firestore in Flutter, check out the following resources:

  • Related