一般來說,我是單元測驗的新手。我正在嘗試從我的 DataRepository 測驗簡單的方法。
按照此鏈接但似乎已棄用:https ://utkarshkore.medium.com/writing-unit-tests-in-flutter-with-firebase-firestore-72f99be85737
class DataRepository {
final CollectionReference collection =
FirebaseFirestore.instance.collection('notes');
//Retour de models a la place de snapshots
Stream<QuerySnapshot> getStream() {
return collection.snapshots();
}
Stream<QuerySnapshot> getStreamDetail(String id) {
return collection.doc(id).collection('tasks').snapshots();
}
Stream<List<Note>> noteStream() {
final CollectionReference collection =
FirebaseFirestore.instance.collection('notes');
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;
}
}
到目前為止,這是我的測驗檔案的樣子:
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);
});
}
第一個實體向我拋出這個錯誤
The argument type 'MockCollectionReference' can't be assigned to the parameter type 'CollectionReference<Map<String, dynamic>>'
我非常感謝測驗該方法的幫助。
新編輯:
void main() {
test('should return data when the call to remote source is succesful.',
() async {
final FakeFirebaseFirestore fakeFirebaseFirestore = FakeFirebaseFirestore();
final DataRepository dataRepository = DataRepository();
final CollectionReference mockCollectionReference =
fakeFirebaseFirestore.collection(dataRepository.collection.path);
final List<Note> mockNoteList = <Note>[];
for (Note mockNote in mockNoteList) {
await mockCollectionReference.add(mockNote.toJson());
}
final Stream<List<Note>> noteStreamFromRepository =
dataRepository.noteStream();
final List<Note> actualNoteList = await noteStreamFromRepository.first;
final List<Note> expectedNoteList = mockNoteList;
expect(actualNoteList, expectedNoteList);
});
}
uj5u.com熱心網友回復:
您可以使用fake_cloud_firestore來模擬 Firestore 實體,方法是使用它的FakeCloudFirestore物件來代替實際FirebaseFirestore物件。
一個例子:
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);
});
解釋:
上面的測驗對您的代碼做出以下假設:
- 您將
FirebaseFirestore物件傳遞給DataRepository物件。 - 您的物件上有一個
toSnapshot方法,Note可以將您的Note物件轉換為Map<String, dynamic>物件。
測驗按以下方式進行:
- It creates the necessary objects needed for the test i.e the
FakeFirebaseFirestoreobject, theDataRepositoryobject, the mockCollectionReferenceobject and the mock data to be passed into the mock collection reference (mockNoteList). - It adds the data into the mock collection reference.
- It gets the data using the
DataRepository'snoteStreammethod. - It asserts that the actual data from the
DataRepositoryis 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:
- FlutterFire's Documentation on Testing, an overview on how to use the
fake_cloud_firestorepackage in widget tests in Flutter. - Mocking and Testing Firestore Operations in Flutter Unit Tests | Part 1 (Documents and Collections), an article about using the
fake_cloud_firestorepackage to test Firestore operations in Flutter Unit Tests, written by me.
Update
Add the FirebaseFirestore object as one of your constructor parameters and use that instead of FirebaseFirestore.instance.
Update your DataRepository to this below:
class DataRepository {
DataRepository({required this.firestore});
final FirebaseFirestore firestore;
CollectionReference get collection =>
firestore.collection('notes');
//Retour de models a la place de snapshots
Stream<QuerySnapshot> getStream() {
return collection.snapshots();
}
Stream<QuerySnapshot> getStreamDetail(String id) {
return collection.doc(id).collection('tasks').snapshots();
}
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;
}
}
Updated DataRepository Usage:
- In tests:
final FakeFirebaseFirestore fakeFirebaseFirestore = FakeFirebaseFirestore();
final DataRepository dataRepository =
DataRepository(firestore: fakeFirebaseFirestore);
- In the app:
final FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
final DataRepository dataRepository =
DataRepository(firestore: firebaseFirestore);
uj5u.com熱心網友回復:
這應該可以解決您的問題:指定 CollectionReference 的型別。這邊走:
class MockCollectionReference extends Mock implements CollectionReference<Map<String, dynamic>> {}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/440123.html
