-
-
Save utkarsh-UK/1a1d2c25fad9cbbc19df5c3a26655a82 to your computer and use it in GitHub Desktop.
| import 'package:cloud_firestore/cloud_firestore.dart'; | |
| class MockFirestore extends Mock implements FirebaseFirestore {} | |
| class MockCollectionReference extends Mock implements CollectionReference {} | |
| class MockDocumentReference extends Mock implements DocumentReference {} | |
| class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} | |
| void main() { | |
| MockFirestore instance; | |
| MockDocumentSnapshot mockDocumentSnapshot; | |
| MockCollectionReference mockCollectionReference; | |
| MockDocumentReference mockDocumentReference; | |
| setUp(() { | |
| instance = MockFirestore(); | |
| mockCollectionReference = MockCollectionReference(); | |
| mockDocumentReference = MockDocumentReference(); | |
| mockDocumentSnapshot = MockDocumentSnapshot(); | |
| }); | |
| //Get data from firestore doc | |
| test('should return data when the call to remote source is successful.', () async { | |
| when(instance.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.get()).thenAnswer((_) async => mockDocumentSnapshot); | |
| when(mockDocumentSnapshot.data()).thenReturn(responseMap); | |
| //act | |
| final result = await remoteDataSource.getData('user_id'); | |
| //assert | |
| expect(result, userModel); //userModel is a object that is defined. Replace with you own model class object. | |
| }); | |
| //Add data to firestore doc | |
| //This demonstrates chained call like (instance.collection('path1').doc('doc1').collection('path2').doc('doc2').add(data)); | |
| //We return the same mocked objects for each call. | |
| test('should get data from nested document.', () async { | |
| // arrange | |
| when(instance.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.add(any)).thenAnswer((_) async => mockDocumentReference); | |
| when(mockDocumentReference.id).thenReturn(messageID); | |
| when(mockDocumentSnapshot.data()).thenReturn(messageData); | |
| //act | |
| final result = await remoteDataSource.addData(userID, notificationID); | |
| //assert | |
| expect(result, notificationID); | |
| }); | |
| //Get list of documents from firestore. | |
| test('should get list of all the documents.', () async { | |
| // arrange | |
| when(instance.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.get()).thenAnswer((_) async => mockDocumentSnapshot); | |
| when(mockDocumentSnapshot.data()).thenReturn(roomsMap); | |
| when(mockDocumentReference.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.get()).thenAnswer((_) async => mockQuerySnapshot); | |
| when(mockQuerySnapshot.docs).thenReturn([mockQueryDocumentSnapshot]); | |
| when(mockQueryDocumentSnapshot.data()).thenReturn(membersMap); | |
| //act | |
| final result = await remoteDataSource.fetchUsers(); | |
| //assert | |
| expect(result, users); | |
| }); | |
| //Delete doc in firestore. | |
| test('should delete a doc and return true.', () async { | |
| // arrange | |
| when(instance.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.delete()).thenAnswer((_) async => Future.value()); | |
| //act | |
| final result = await remoteDataSource.joinSquad(); | |
| //assert | |
| expect(result, true); | |
| }); | |
| //Mock query methods like orderBy(), limit(). | |
| test('should return previous messages when getting data is successful.', () async { | |
| // arrange | |
| when(instance.collection(any)).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.collection('messages')).thenReturn(mockCollectionReference); | |
| when(mockCollectionReference.doc(lastMessageID)).thenReturn(mockDocumentReference); | |
| when(mockDocumentReference.get()).thenAnswer((realInvocation) async => mockDocumentSnapshot); | |
| when(mockCollectionReference.orderBy('timestamp', descending: true)).thenReturn(mockQuery); | |
| when(mockQuery.startAfterDocument(mockDocumentSnapshot)).thenReturn(mockQuery); | |
| when(mockQuery.limit(20)).thenReturn(mockQuery); | |
| when(mockQuery.get()).thenAnswer((_) async => mockQuerySnapshot); | |
| when(mockQuerySnapshot.docs).thenReturn([mockQueryDocumentSnapshot]); | |
| when(mockQueryDocumentSnapshot.data()).thenReturn(message); | |
| //act | |
| final result = await remoteDataSource.loadPreviousMessages(roomID: roomID, lastFetchedMessageID: lastMessageID); | |
| //assert | |
| expect(result, messages); | |
| }); | |
| } |
Hey, I finally pass the firestore unit test. But again I am stuck in a point where I need to test a function called writeNewUser that returns a void by creating a new document when it called. I tried to test that as follows using verify()
verify(instance.collection(''Name"))
verify(mockCollectionReference.doc(''Name''))
but only the first verify method gets call but the writeNewUser() function executes without any error perfectly as I expected.
You may update this for null-safety.
Right now, I get
type 'MockCollectionReference<Object?>' is not a subtype of type 'MockCollectionReference<Map<String, dynamic>>' in type cast
on when(firestore.collection("users")).thenReturn(userCollection);
I figured it out how to use your implementation In null-safety and with the code generation of Mockito.
Code gen:
Map<String, bool> getData() {
return {}; //this will be overriden
}
@GenerateMocks(
[
FirebaseFirestore,
CollectionReference,
DocumentReference,
QuerySnapshot,
],
customMocks: [
MockSpec<QueryDocumentSnapshot>(
as: #MockQueryDocumentSnapshot, fallbackGenerators: {#data: getData}),
],
)
Then in your declaration of your mocked vars you need to tell the compiler what you are actually extending:
late MockFirebaseFirestore firestore;
late MockCollectionReference<Map<String, dynamic>> userCollection;
late MockDocumentReference<Map<String, dynamic>> doc;
late MockCollectionReference<Map<String, dynamic>> notificationCollection;
late MockQuerySnapshot<Map<String, dynamic>> querySnapshot;
late MockQueryDocumentSnapshot<Map<String, dynamic>> queryDocumentSnapshot;
...
setState
...
Here is a usage of my mocked methods:
when(firestore.collection("users")).thenReturn(userCollection);
when(userCollection.doc("1")).thenReturn(doc);
when(doc.collection("notifications")).thenReturn(notificationCollection);
when(notificationCollection.get()).thenAnswer((_) async => querySnapshot);
when(querySnapshot.docs)
.thenAnswer((realInvocation) => [queryDocumentSnapshot]);
when(queryDocumentSnapshot.data())
.thenAnswer((realInvocation) => {"message": true});
To understand why the custom mock is needed read this issue and the readme of the Mockito repo.
Hope that helps anyone.
when(instance.collection("sold")).thenReturn(mockCollectionReferenceSold);
when(mockCollectionReferenceSold.doc("abc"))
.thenReturn(mockDocumentReferenceSold);
when(mockDocumentReferenceSold.set({
'appointmentID': "tAppointmentID",
'date': DateTime.parse("2020-12-05 20:18:04Z"),
'description': "test description",
})).thenAnswer((_) async => mockDocumentSnapshotSold);
print(mockDocumentSnapshotSold.id);prints null
any idea?
why data hasnt inserted into firestore?
If what You write is your whole code, then you are refering to mockDocumentSnapshotSold.id, but didn't call mockDocumentReferenceSold
@Babwenbiber could u show in code how and where it shoudl be called? i am not getting you.
I am also stuck in the same as @sath26.
prints null
sath26 commented on Sep 16 •
when(instance.collection("sold")).thenReturn(mockCollectionReferenceSold);
when(mockCollectionReferenceSold.doc("abc"))
.thenReturn(mockDocumentReferenceSold);
when(mockDocumentReferenceSold.set({
'appointmentID': "tAppointmentID",
'date': DateTime.parse("2020-12-05 20:18:04Z"),
'description': "test description",
})).thenAnswer((_) async => mockDocumentSnapshotSold);
print(mockDocumentSnapshotSold.id);
prints null
any idea?
why data hasnt inserted into firestore?
How can we test streams in firestore and model class.
//arrange
when(instance.collection("todos")).thenReturn(mockCollectionReference);
when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference);
when(mockDocumentReference.collection("todos"))
.thenReturn(mockCollectionReference);
when(mockCollectionReference.snapshots())
.thenReturn(mockQuerySnapshotStream);
when(await mockQuerySnapshotStream.toList())
.thenReturn(mockQuerySnapshotList);
when(mockQuerySnapshotList.map((e) {
final List retVal = [];
for (final DocumentSnapshot doc in e.docs) {
retVal.add(TodoModel.fromDocumentSnapshot(documentSnapshot: doc));
}
return retVal;
}));
//test
int i = 0;
stream.listen(
expectAsync1((event) {
expect(event.content, actual[i].content);
i++;
}, count: take),
);
I have followed all the steps and even added a separate file
mock.dart(just copy pasted code from here https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/test/mock.dart) in order to fix problems withFirebase.initializeApp(). I ended up getting the following errors: