Jest testing firebase functions with emulator-suite

Timo Santi
3 min readNov 19, 2019

I have been working quite a while with testing my code. I have found it quite hard to test my firebase functions code. Functions are doing all my backend work so, those are the most critical, so therefore I wanted to get good testing coverage. I have been reading a lot of firebase documentation and articles and Slack or Stack Overflow messages regarding testing firebase functions.

I wanted to share my solution so that it might help anyone else who has the same challenges I had. I also wan’t to get your feedback so that I can learn to be better tester. This is my first article, so be gentle with your feed back 😀.

I’m using mostly firestore triggered functions. I had offline and online tests based on documentation by great Firebase folks. I wrote these using Jest by learning from tutorial wrote by Jeff Delaney.

But I was not too happy with my tests 😟. I felt that offline tests needed to much mocking of firebase-admin features and also needed too much fixing when I refactored something in my functions. Online tests using dedicated firebase-project for testing were easier to write and also covered my functions better, but were flaky and slow. I wanted better isolation between tests and have also possibility to run tests offline and in parallel.

Solution

I wanted to change my online test to run offline using firestore emulator from firebase-emulator-suite instead of dedicated online testing project. I also wanted to isolate tests to use different project id so that I can run tests in parallel.

Install dependencies

Install emulator suite globally

npm install -g firebase-tools

Install firebase-functions-test and jest locally

npm install --save-dev firebase-functions-test jest 

Start emulators

Start firestore and realtime emulators. Note! Don’t start functions emulator.

firebase emulators:start --only firestore,database

Tested cloud function

index.ts

Sample cloud function to be tested is triggered when firestore document is created. It’s quite simple. It will add createdAt timestamp from context.timestamp, creates lowercase name field and updates counts in aggregated counts document using special firestore increment value. I added Timestamp and FieldValue to this sample, because those were something I struggled with.

Integration tests

Mocks

I’m initializing firebase-functions-test SDK in offline mode.

[Updated] I’m defining custom Project Id for this file. Then I’m initializing admin app with this Project Id using inititalizeApp method from firebase-admin. First I set up environment variables so that initializeApp will initialize firebase app to connect emulator instance instead of online firestore.

Actual tests are quite simple. In every describe I’m wrapping tested cloud function to wrapped variable. Before each test I’m cleaning database, which is SO simple with firebase/testing.

I’m writing actual documents to database and getting snapshots from there. Then I run the function under test using my wrapped function.

After function execution I’m reading results from database and asserting these using normal Jest helpers.

There is sample repo including all the files in my github.

https://github.com/diginikkari/jest-testing-firebase-functions-with-emulator-suite

Ok, I have to admit that I feel bit dirty in a way I use these two testing libraries together. These clearly are not meant to be used together, but I haven’t found any official way to do the same. Firebase emulator-suite is still quite new and I believe it will evolve and make this obsolete at some point.

What I accomplished? Now it is easy to write tests which are simple and readable. Each test is run in clear database so there is no need to manually clean any created documents. Every test file is using own dedicated offline firestore database instance with unique id, which makes it possible to run tests in parallel without tests effecting each other. This makes function tests blazing fast 🚀.

I hope that someone will find this article helpful. Have a nice Day!

--

--

Timo Santi

Entrepreneur, coder and tech enthusiast. CEO/Founder of Santi Consulting. www.santicon.fi