I am designing a backend api (for android and iOS apps) around HttpsCallable cloud functions. It becomes quite cumbersome to test them through the app, so I wish to switch to unit testing the functions (before production deployment) using the firebase-functions-test
tool. I have been following this unit testing tutorial.
I am having some issues running the unit tests in online mode. Let me provide some details.
Here is my `package.json' content:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"test": "mocha --reporter spec"
},
"engines": {
"node": "8"
},
"dependencies": {
"@google-cloud/tasks": "^1.9.0",
"@googlemaps/google-maps-services-js": "^2.0.2",
"chai": "^4.2.0",
"firebase-admin": "^8.6.0",
"firebase-functions": "^3.3.0",
},
"devDependencies": {
"eslint": "^5.12.0",
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.1.7",
"mocha": "^7.1.1"
},
"private": true
}
I am using google APIs (Directions, Geocoding etc) from firebase backend, therefore to be able to access them while running my tests, I configured my tests located at test/index.test.js
as recommended in the Unit testing tutorial as follows:
const firebaseConfig = {
apiKey: ...,
authDomain: ...,
databaseURL: "https://my-project.firebaseio.com",
projectId: "my-project",
storageBucket: "my-project.appspot.com",
messagingSenderId: ********,
appId: *********
};
const test = require('firebase-functions-test')(firebaseConfig
, 'path_to_json_keyfile/myproject.json');
Below is the sample test code. Note that all my callable functions return HttpsError, and the test below, simply checks for the code
field of HttpsError
, if its ok
, the test passes. The functions I am testing reside in a separate rides.js
file, which the index.js
exports as exports.rides = require(./rides.js)
(not shown below)
const chai = require('chai');
const assert = chai.assert;
describe('Cloud functions', () => {
let rideFunctions;
before(() => {
rideFunctions = require('../index.js');
});
after(() => {
test.cleanup();
});
describe('getRideEstimate', () => {
it('should return ok', async () => {
data = {
riderType: 1,
pickup_lat: 37.0,
pickup_lng: -122,
dropoff_lat: 37.01,
dropoff_lng: -122.01,
scheduledTime: 1585939000,
ts: 1585939000,
tz_id: "uslax"
}
context = {
auth: {
uid: AUTH_ID_FOR_USER_ACCOUNT
}
};
const wrappedGetRideEstimate = test.wrap(rideFunctions.rides.getRideEstimate);
let httpsError = await wrappedGetRideEstimate(data, context);
return assert.equal(httpsError.code, 'ok');
});
})
describe('testCallable', () => {
it('should return ok', async () => {
data = {}
context = {}
const wrappedTestCallable = test.wrap(rideFunctions.rides.testCallable);
let httpsError = await wrappedTestCallable(data, context);
return assert.equal(httpsError.code, 'ok');
})
})
})
Problem
- My simple
testCallable
function of the form
exports.testCallable = functions.https.onCall((data, context) => {
console.log('testCallable');
return new functions.https.HttpsError('ok', '', '');
})
passes the test (as expected) but inexplicably, it seems it is running in the offline mode, as there is no record of it on cloud function logs in Firebase Console. Also, if I disable connectivity of my laptop, the test result remains the same suggesting that somehow this function is running in the offline mode.
My
getRideEstimate
function which calls the googleDirections
API, returns a lengthy400
error indicating some issue with forming the request to Directions API. I don't know if this error is related to the first problem, but since the Directions API call is embedded deeper inside thegetRideEstimate
function, it does suggest that the function is getting called, but somehow the API call is failing.Is there any other way to test HttpsCallable functions in online mode?