Flutter - Test Firestore
Published: 2022-07-06 07:40:23

## Intro

Today, I would like to share how to test Firestore in a Flutter environment. If you tried already, then you probably know that the Firestore connection does not work in test mode. So, you need to mock the Firestore instance. When it comes to Flutter, you can use [fake_cloud_firestore](https://pub.dev/packages/fake_cloud_firestore) which is mentioned in [FlutterFire](https://firebase.flutter.dev/docs/testing/testing/).

In this post, I will explain how to write repository unit tests that interact with Firestore.

If you just want to learn how to test Firestore, you wouldn’t need an actual Firebase Project.

## Setup

First, create a test project.

```bash
flutter create test_fake_cloud_firestore
```

Second, you need to install the packages below.

```bash
flutter pub add cloud_firestore
flutter pub add fake_cloud_firestore
```

- `cloud_firestore`  → need for using type
- `fake_cloud_firestore` → need for mocking Firestore

## Write `TestRepository` using Firestore

Now, under the `lib` directory, create `test_repository.dart` 

```bash
cd test_fake_cloud_firestore
touch ./lib/test_repository.dart
```

Then, fill out the above file with `TestRepository` class that has a method for interacting with Firestore. Since this is only for testing, you don’t need to have an actual Firebase project. The path of collection or doc will be used in the test file, so make up any path you want and use that path later on.

Below is the class that I’ve tested with.

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

class TestRepository {
  final FirebaseFirestore firestore;
  TestRepository({required this.firestore});

  late final countDoc = firestore.doc('test/doc_12345');

  Future<int?> fetch() async {
    final snapshot = await countDoc.get();
    return snapshot.data()?['count'];
  }
}
```

Note that I handed over the Firestore instance through the constructor. By injecting dependency(in this case, Firestore instance), you will have a repository that is easy to test with the mock instance.

## Create `test_repository_test.dart`

After that, you need to create a test file whose name ends with `_test` under the `test` directory.

```bash
touch ./test/test_repository_test.dart
```

In a test file, declare `void main()` function which will be run when you run `flutter test` command.

```dart
void main() {}
```

## Write test content using `FakeFirestore`

Now, fill the main function with the test code.

```dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fake_cloud_firestore/fake_cloud_firestore.dart';
import 'package:test_fake_cloud_firestore/test_repository.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('Test fake_cloud_firestore', () {
    // 1
    final firestore = FakeFirebaseFirestore();
    late TestRepository testRepository;
    setUp(
      () {
        // 2
        testRepository = TestRepository(firestore: firestore);
        // 3
        setDummyFirestore(firestore);
      },
    );

    test('Test fetch data', () async {
      // 4
      final result = await testRepository.fetch();
      expect(result, 2);
    });
  });
}

setDummyFirestore(FirebaseFirestore firestore) {
  firestore.collection('test').doc('doc_12345').set({
    'count': 4,
  });
}
```

- First, use `flutter_test` package to run the test easily. (`group`, `setUp`, `test`, `expect`)
- I will explain the steps by number.
    1. Initialize `FakeFirebaseFirestore` at first. 
    2. In `setUp`, initialize `testRepository` with a fake Firestore instance.
    3. Then, set up data in fake Firestore for the test. In this case, need to set ‘count’ field in ‘test/doc_12345’ with a number.
    4. Run the test method and check if `result` variable has the right value.

Finally, run the test with the below command in a project root directory.

```bash
flutter test
```

This test should fail followed by logging different values (2 and 4).

 This means that now you can test your Firebase Firestore connection logic safely with the mock instance.

## Conclusion

Firebase and Flutter are often used together. I hope this article helped your testing practice with them!

Cheers!

<a href="https://www.buymeacoffee.com/swimmingkiim" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/arial-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>