firebase-functions-test icon indicating copy to clipboard operation
firebase-functions-test copied to clipboard

Cannot invoke Firestore from tests

Open bwhrsc opened this issue 4 years ago • 2 comments

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"

bwhrsc avatar Jun 25 '20 02:06 bwhrsc

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

bwhrsc avatar Jun 26 '20 02:06 bwhrsc

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

elvisun avatar Jun 30 '21 17:06 elvisun