简体   繁体   中英

Why can't I access .env variables when unit testing Firebase (Cloud) Functions with firebase-functions-test, mocha, and Emulator Suite?

I have a Firebase Project using Functions, Storage, and Auth that I would like to do some rudimentary unit testing using mocha and the Emulator Suite (already working for local development).

I've read the documentation front to back several times and I don't seem to understand how to set this up. My specific challenge currently is that I cannot seem to get a simple function that returns a defined environment variable to return properly due to the environment variables not loading.

My setup is as follows:

functions/index.js

const functions = require("firebase-functions")
const admin = require('firebase-admin')
admin.initializeApp()
const { getFunctions } = require('firebase-admin/functions')
...
exports.requiresEnvVariable = functions.https.onCall((data, context) => {
  return process.env.MYENV_VARIABLE || ':('
})
  

functions/tests/test.spec.js

const { expect } = require("chai")
const sinon = require("sinon")
const admin = require("firebase-admin")
  
console.log(process.env.GCLOUD_PROJECT)
  
const test = require("firebase-functions-test")({
  projectId: process.env.GCLOUD_PROJECT
}, 'serviceAccount.json')

// I've played with calling this here and stubbing, asmentioned in the docs. Nothing seems to work.
//admin.initializeApp()
//adminInitStub = sinon.stub(admin, 'initializeApp')

const myFunctions = require("../index")

describe("Unit tests", () => {
  it("A good and cool test description", async () => { 
    const wrapped = test.wrap(myFunctions.getTToken)
    const data = {}
    const result = await wrapped(data)
    expect('yayitworked').to.eql(result)
  })
})

functions/package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase emulators:start --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log",
    "tests": "mocha --exit tests/*.spec.js"
  },
  "engines": {
    "node": "18"
  },
  "main": "index.js",
  "dependencies": {
    "axios": "^1.1.3",
    "cors": "^2.8.5",
    "firebase-admin": "^11.4.1",
    "firebase-functions": "^4.1.1",
  },
  "devDependencies": {
    "chai": "^4.3.7",
    "firebase-functions-test": "^3.0.0",
    "mocha": "^10.2.0",
    "sinon": "^15.0.1"
  },
  "private": true
}

functions/.env

MYENV_VARIABLE=yayitworked

And I run from the functions folder:

firebase emulators:exec 'npm run tests'

giving AssertionError: expected ':(' to deeply equal 'yayitworked'

Why can I not access the environment variables?

Short answer is that firebase-functions-test package doesn't load environment variables stored in .env file. You'd need to load the .env file manually as part of your mocha test setup by using packages like https://www.npmjs.com/package/dotenv .

Longer answer is that the setup described in the question - combining the Firebase Emulator and firebase-functions-test package - probably isn't working as you expect them to work.

When running

firebase emulators:exec 'npm run tests'

we get 2 separate instances of requiresEnvVariable function:

  1. One spun up by the Firebase Emulator. This function would have loaded the .env variables because Firebase Emulator includes logic to load environment variables in appropriate .env files before spinning up a function.

  2. One spun up by your mocha test. This "function" is really a plain JS function and will inherit environment variables in the parent process.

Tests written using firebase-functions-test are testing (2) function, not (1). In order to invoke the function (1) spun up by the Firebase Emulator, you'd need to make HTTP request to the URL exposed by the Firebase Emulator (see sample code )

(Side note: firebase-functions-test package was released years before Firebase Emulator so isn't "Firebase emulator-aware" so to speak.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM