You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
How to Test Firebase Cloud Functions With Jest
Episode 111 written by Jeff DelaneyHealth Check: This lesson was last reviewed on and tested with these packages:
- CloudFunctions v1.x
- Jest v23
Find an issue? Let's fix it
Source code available to pro members. Learn more
Full source code for How to Test Firebase Cloud Functions With Jest on Github
Firebase Cloud Functions makes building a serverless backend easy and fun, but the proper way to write unit tests in this environment is not exactly clear. In this episode, I will show you how to setup a testing environment for your functions and use Jest to implement unit tests.
Jest is my preferred testing framework for Cloud Functions, but the official docs use Mocha, Sinon, and Chai. Either approach works.
Test Environment Setup
There are two ways to test functions - offline and online. With offline testing, you will create mocks and stubs to simulate a Cloud Function’s arguments. With online testing you will make real requests to Firebase using a dedicated development project, so your tests will read/write live data.
Should I write offline or online tests? It’s a matter of personal preference, but I do most of my testing online with a dedicated Firebase project for development. Offline tests require a ton of stubs, which can be cumbersome to setup and are more susceptible to human error.
Let’s initialize functions and create a couple test files.
firebase init functions # select TypeScript |
Install Jest Typescript
Jest requires some setup, but by comparison to other test frameworks it is very minimal. Ideally, Jest is the only package you need to install to handle all Cloud Function testing.
Install Jest TypeScript (and Jest globally)
npm install --global jest |
Then update the package.json
{ |
Now you’re ready to start testing. Use the watchAll
flag to run tests in the background. Optionally add coverage
to show code coverage.
jest --watchAll --coverage |
Offline Testing Setup
Offline tests…
- run faster
- require more code to setup mocks/stubs
- do not make any real changes to your data
// functions/test/offline.test.ts |
Online Testing Setup
Online tests…
- run slower
- are easier to write (fewer stubs needed)
- should use a project isolated from your production app
To setup online tests, you need to download your service account from the Firebase console.
Save the project credentials to a file as /functions/service-account.json
Do not expose the service account publicly - it allows full write access to your Firebase project.
// functions/test/online.test.ts |
Firestore Function Tests (Online)
Cloud Function
Our first cloud function runs when a Firestore document is created and simply converts a property on the document to lowercase.
import * as functions from 'firebase-functions'; |
Spec
Let’s test our function with live data to ensure that data gets updated in the database properly. Notice how we need to use testEnv.wrap(lowercaseBio)
to make the function callable in our tests. This gives us a function that returns a Promise, therefore we can await the results in the spec. When the promise resolves, the database should be updated with the lowercase value.
describe('downcaseBio', () => { |
import { lowercaseBio } from '../src'; |
Auth Function Tests (Online)
Cloud Function
The auth function runs after a new user signup and will create a Firestore document under the UID to give them an initial ranking of noob.
export const createUserRecord = functions.auth |
Spec
The auth function is tested in the same manner as Firestore. In fact, all background functions (Firestore, RTDB, Auth, Storage, PubSub) follow similar testing patterns. Notice how we use testEnv.auth.makeUserRecord(...)
. This allows us to generate a fake user record specifically for this test with the values we specify.
describe('createUserRecord', () => { |
describe('createUserRecord', () => { |
HTTP Function Tests (Offline)
Cloud Function
The HTTP function simulates how a credit card payment request might work. If the request is missing a credit card in the body then we send back an error.
export const makePayment = functions.https.onRequest((req, res) => { |
Spec
Let’s make sure this behavior works property in offline mode. The key takeaway on this snippet is the stubbed request/response. Notice how we put the expectation inside the send
method of the response, then call makePayment
with our stubs.
import { makePayment } from '../src'; |
The End
There are many different possibilities when it comes to testing Cloud Functions. Ultimately, the right strategy depends on the critical business needs of the app, but live testing with Jest is a reliable approach for many situations. Let me know if you want to see any other testing strategies in the comments.