'Mock function in Firebase local emulator

Such as described here, I'm using local emulator (on-line) to make tests im my cloud functions.

Index.js:

    var status = 200;
    exports.saveAndSendMail = functions.https.onCall( async (req, res) => {
    try{
        let jsons = req.body;

        await saveInfirestore(jsons);

        await sendMail("Data saved", jsons);

    } finally {
        closeConnection(res, status);
    }
    async function saveInfirestore(json) {
    //execute business logic and save in firestore (irrelevant for this question)
    }


    function closeConnection (res, status){
        res.sendStatus(status);
        res.end();
    }


    async function sendMail(title, message) {
    try {
       AWS.config.loadFromPath('./config_mail.json');

        // Create sendEmail params 
        var params = {
        Destination: { 
            ToAddresses: [
            '[email protected]'
            ]
        },
        Message: { /* required */
            Body: { /* required */
        Html: {
                Charset: "UTF-8", 
                Data: JSON.stringfy(message);
                }
            },
            Subject: {
                Charset: 'UTF-8',
                Data: title
            }
            },
        Source: '"Origin" <[email protected]>',
        ReplyToAddresses: [
            '[email protected]'
        ]
        };

        // Create the promise and SES service object
        var sendPromise = new AWS.SES({apiVersion: '2022-17-01'}).sendEmail(params).promise();
    }
    catch(e){
        throw e;
    }
    // Handle promise's fulfilled/rejected states
    sendPromise.then(
    function(data) {
        console.log(data.MessageId);
    }).catch(
        function(err) {
        console.error(err, err.stack);
    });
  }

index.test.js

    const { expect } = require("chai");
    const admin = require("firebase-admin");
    
    const test = require("firebase-functions-test")({
        projectId: process.env.GCLOUD_PROJECT,
    });
    
    const myFunctions = require("../index");
    
    describe("Unit tests", () => {
      after(() => {
        test.cleanup();
      });
    
      it("test if save is correct", async () => {
        const wrapped = test.wrap(myFunctions.saveAndSendMail);
    
          const req = {
            body: [{
              value: 5,
              name: 'mario'
            }]
          };
    
        const result = await wrapped(req);
    
        let snap = await db.collection("collection_data").get();
    
        expect(snap.size).to.eq(1);
        
        snap.forEach(doc => {
    
            let data = doc.data();
    
            expect(data.value).to.eql(5);
            expect(data.name).to.eql('mario');
        });
    
    });

I execute it with: firebase emulators:exec "npm run test"

I have 2 problems.

1 - When execute, I receive the error TypeError: res.sendStatus is not a function. If I comment closeConnection call in block finally (index.js), this code run perfectly and all tests and "expect" run with success. But, this correct way is mock this method or mock 'res' calls. I tried mock with something like this:

       const res = {
            sendStatus: (status) => {
            },
            end: () => {
            }
          }
    
    const result = await wrapped(req, res);

But, I receive this error:

 Error: Options object {} has invalid key "sendStatus"
  at /home/linuxuser/my-project/firebase/functions/myfolder/node_modules/firebase-functions-test/lib/main.js:99:19
  at Array.forEach (<anonymous>)
  at _checkOptionValidity (node_modules/firebase-functions-test/lib/main.js:97:26)
  at wrapped (node_modules/firebase-functions-test/lib/main.js:57:13)
  at Context.<anonymous> (test/index.test.js:50:26)
  at processImmediate (node:internal/timers:464:21)

Problem 2:

I'm not wish receive an e-mail each time that tests executes. How I mock sendMail function?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source