Agung
Agung

Reputation: 13863

how to properly initialize firebase functions test using cloud function?

I am using

so I want to perform unit testing for my firestore trigger function using firebase cloud function, I read the steps from the documentation in here.

I want to perform unit test using Firebase Emulator. so I assume I will initialize the SDK in offline mode. the documentation said that

If you would like to write completely offline tests, you can initialize the SDK without any parameters:

so I initialize it like this

import * as firebase from "firebase-functions-test";

const test = firebase();
const wrapped = test.wrap(myFunctions.onCreate);

// rest of my test code

but when I run the test, I have this error:

Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.

so even though I will use Firebase emulator (offline), it seems I need to provide the credential, which is the step if online mode is used, like explained from documentation in here

so I initialize the SDK like this

import * as firebase from "firebase-functions-test";

const test = firebase({
    databaseURL: "https://xxx-b843e.firebaseio.com",
    projectId: "xxx-b843e",
}, "../../../service-account.json");

const wrapped = test.wrap(myFunctions.onCreate);

// rest of my test code

but when I run the test, I have another error

{"severity":"WARNING","message":"Warning, FIREBASE_CONFIG and GCLOUD_PROJECT environment variables are missing. Initializing firebase-admin will fail"}

Error: The file at ../../../service-account.json does not exist, or it is not a file. ENOENT: no such file or directory, lstat '/Users/xxx/Documents/service-account.json'

the service account json file doesn't exist? I believe I have set the path correctly like this

enter image description here

in fact, I use intellisense to guide me to service-account.json path enter image description here

the service-account.json file is like the image below, i get it from firebase project overview --> project settings --> service accounts --> generate new private key

enter image description here

what should I do if I want to initialize firebase functions test SDK in Firebase emulator?

Upvotes: 4

Views: 2403

Answers (3)

Exac
Exac

Reputation: 53

Getting rid of the warning should be as simple as adding the following to your jest.preset.js (or whatever code runs before your unit tests run).

const test = require('firebase-functions-test')();

https://firebase.google.com/docs/functions/unit-testing#offline-mode

Upvotes: 0

Ben Winding
Ben Winding

Reputation: 11827

Explanation

Error: The file at ../../../service-account.json does not exist

That error means that the service-account.json file could not be found at runtime (when you started the emulator), because the relative path is incorrect.

in fact, I use intellisense to guide me to service-account.json path

The path that intellisense suggests may not be the correct relative to the directory the code is executing in. This is because typescript is compiled before it's run, usually from within a lib or dist folder, which means the relative path needs to be changed.

Solution 1

You can use an absolute path /my/absolutepath/to/service-account.json, this is a fast way to resolve this problem, but isn't very portable.

Solution 2

Experiment with different amounts of ../../ to find the exact relative path of the service-account.json. Try using:

  • ../../service-account.json
  • ../../../service-account.json
  • etc ... (until it works)

It's most likely only off by a few ../

Upvotes: 1

Hiranya Jayathilaka
Hiranya Jayathilaka

Reputation: 7438

To use the offline mode you need to stub API calls like admin.initializeApp(). See the example given at https://firebase.google.com/docs/functions/unit-testing#importing_your_functions

// If index.js calls admin.initializeApp at the top of the file,
// we need to stub it out before requiring index.js. This is because the
// functions will be executed as a part of the require process.
// Here we stub admin.initializeApp to be a dummy function that doesn't do anything.
adminInitStub = sinon.stub(admin, 'initializeApp');
// Now we can require index.js and save the exports inside a namespace called myFunctions.
myFunctions = require('../index');

To test against the emulator you need to the initialize the test SDK with an emulator URL. Your file not found error is probably due to a problem with resolving relative paths. Try providing an absolute path and see if that works.

Upvotes: 0

Related Questions