firebase-functions-test
firebase-functions-test copied to clipboard
Cannot invoke Firestore from tests
Developing Google cloud functions locally. Trying to test functions that invoke Firestore. Here is a minimal example.
- Emulators are running.
- The function addMessage() works completely fine when invoked from the browser.
- The function fails with error TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. when invoked from tests.
- Question: Why is this error occurring and how can I invoke the Firestore function successfully from the tests?
functions/index.js:
require ('dotenv').config();
const functions = require ('firebase-functions');
const admin = require ('firebase-admin');
admin.initializeApp();
exports.addMessage = functions.https.onRequest (async (req, res) => {
const original = req.query.text;
const writeResult = await admin.firestore().collection ('messages').add ({text: original});
const docSnap = await writeResult.get();
const writtenText = docSnap.get ('text');
res.send (`Message with text: ${writtenText} added.`);
});
functions/test/index.test.js:
const admin = require ('firebase-admin');
const firebase_functions_test = require ('firebase-functions-test')({
projectId: 'my-project-id'
}, '/path/to/google-application-credentials.json');
const testFunctions = require ('../index.js');
describe ('addMessage()', () => {
it ('returns Message with text: Howdy added.', (done) => {
const req = {query: {text: 'Howdy'} };
const res = {
send: (body) => {
expect (body).toBe (`Message with text: Howdy added.`);
done();
}
};
testFunctions.addMessage (req, res);
});
});
Starting jest from functions folder:
(Among other test-related output):
FAIL test/index.test.js
● addMessage() › returns Message with text: Howdy added.
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type object
7 | exports.addMessage = functions.https.onRequest (async (req, res) => {
8 | const original = req.query.text;
> 9 | const writeResult = await admin.firestore().collection ('messages').add ({text: original});
| ^
10 | const docSnap = await writeResult.get();
11 | const writtenText = docSnap.get ('text');
12 | res.send (`Message with text: ${writtenText} added.`);
at GrpcClient.loadProto (node_modules/google-gax/src/grpc.ts:166:23)
at new FirestoreClient (node_modules/@google-cloud/firestore/build/src/v1/firestore_client.js:118:38)
at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (node_modules/@google-cloud/firestore/build/src/index.js:326:26)
at ClientPool.acquire (node_modules/@google-cloud/firestore/build/src/pool.js:87:35)
at ClientPool.run (node_modules/@google-cloud/firestore/build/src/pool.js:164:29)
at Firestore.request (node_modules/@google-cloud/firestore/build/src/index.js:983:33)
at WriteBatch.commit_ (node_modules/@google-cloud/firestore/build/src/write-batch.js:496:48)
Caused by: Error:
at WriteBatch.commit (node_modules/@google-cloud/firestore/build/src/write-batch.js:415:23)
at DocumentReference.create (node_modules/@google-cloud/firestore/build/src/reference.js:283:14)
at CollectionReference.add (node_modules/@google-cloud/firestore/build/src/reference.js:2011:28)
at Object.<anonymous>.exports.addMessage.functions.https.onRequest (index.js:9:71)
at Object.addMessage (node_modules/firebase-functions/lib/providers/https.js:50:16)
at Object.done (test/index.test.js:17:19)
Environment:
"node": "10"
"firebase-admin": "^8.12.1",
"firebase-functions": "^3.7.0"
"firebase-functions-test": "^0.2.1",
"jest": "^25.5.4"
Solved - https://stackoverflow.com/questions/62566957/cannot-call-firestore-from-unit-tests/62586875#62586875 This still feels like a workaround, and not sure what the origin of the problem is, so leaving this open
Sorry for the late response here, are you still having issue with this?
Looking at your code I'm not sure if your test is talking to the emulator. You can follow the steps here to make sure your tests talk to the emulator instead of an actual firestore instance. https://firebase.google.com/docs/emulator-suite/connect_firestore#admin_sdks