0

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"
Ben Hogan
  • 55
  • 5
  • 1
    Considering the error of the stack trace, I searched around and it always seems related to the `jest` version. For this reason, could you please try to update its version, following the steps mentioned [here](https://stackoverflow.com/a/46245846/12767257)? In case it's still not working, I believe checking this other post [here](https://github.com/firebase/firebase-admin-node/issues/793), might provide some insights to you. – gso_gabriel Jun 25 '20 at 07:14
  • Thanks @gso_gabriel for your help - the second link was the winner (see answer). Much appreciated :) – Ben Hogan Jun 26 '20 at 02:00
  • 1
    Would you consider changing the title to point out that you're trying to use Firestore from Cloud Functions (not directly from the client). E.g. "Cannot call Firestore from Cloud Function unit tests". It's relevant to the problem, and the current title attracts also people who don't use or need firebase-functions-test. – akauppi Jul 24 '20 at 10:49

1 Answers1

2

Solved by adding jest.config.js to functions/:

module.exports = {
    testEnvironment: 'node'
};

Solution based on this (but NB I needed to place jest.config.js in functions/, not the project root).

Also tried this but appeared to do nothing.

Tests now run perfectly except that they end with a Jest error:

Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

This seems to be harmless.

Thanks @gso_gabriel for the valuable links!

Ben Hogan
  • 55
  • 5