Test Sendgrid implementation with Jest and Mock in node.js

故事扮演 提交于 2019-12-11 14:55:56

问题


I use sendGrid email in my nodejs app and I would like to test it with jest.

This is my app code:

mail.js

const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

const simplemail = () => {
  const msg = {
    to: 'receiver@mail.com',
    from: 'sender@test.com',
    subject: 'TEST Sendgrid with SendGrid is Fun',
    text: 'and easy to do anywhere, even with Node.js',
    html: '<strong>and easy to do anywhere, even with Node.js</strong>',
    mail_settings: {
      sandbox_mode: {
        enable: true,
      },
    },
  };
  (async () => {
    try {
      console.log(await sgMail.send(msg));
    } catch (err) {
      console.error(err.toString());
    }
  })();
};

export default simplemail;

Here is what I've done to test it with jest:

mail.test.js

import simplemail from './mail';
const sgMail = require('@sendgrid/mail');
jest.mock('@sendgrid/mail', () => {
  return {
    setApiKey: jest.fn(),
    send: jest.fn(),
  };
});
describe('#sendingmailMockedway', () => {
  beforeEach(() => {
    jest.resetAllMocks();
  });
  it('Should send mail with specefic value', async () => {
    // sgMail.send.mockResolvedValueOnce([{}, {}]);
    await expect(sgMail.send).toBeCalledWith({
      to: 'receiver@mail.com',
      from: 'sender@test.com',
      subject: 'TEST Sendgrid with SendGrid is Fun',
      text: 'and easy to do anywhere, even with Node.js',
    });
  });
});

I need to fix my code coverage on this file so to put as much test as possible and test if the mail is sent and catch if there is error or now, that's why I've added in mail.js

mail_settings: {
  sandbox_mode: {
    enable: true,
  },
},

I would like to test it with jest and mock sendgrid it but how?


回答1:


Because you use IIFE and async/await in simplemail function, Use setImmediate function to make sure the IIFE is executed before we assert it in unit test case.

Here is the unit test solution:

index.js:

const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

const simplemail = () => {
  const msg = {
    to: "receiver@mail.com",
    from: "sender@test.com",
    subject: "TEST Sendgrid with SendGrid is Fun",
    text: "and easy to do anywhere, even with Node.js",
    html: "<strong>and easy to do anywhere, even with Node.js</strong>",
    mail_settings: {
      sandbox_mode: {
        enable: true
      }
    }
  };
  (async () => {
    try {
      console.log(await sgMail.send(msg));
    } catch (err) {
      console.error(err.toString());
    }
  })();
};

export default simplemail;

index.spec.js:

import simplemail from "./";
const sgMail = require("@sendgrid/mail");

jest.mock("@sendgrid/mail", () => {
  return {
    setApiKey: jest.fn(),
    send: jest.fn()
  };
});

describe("#sendingmailMockedway", () => {
  afterEach(() => {
    jest.resetAllMocks();
    jest.restoreAllMocks();
  });
  it("Should send mail with specefic value", done => {
    const logSpy = jest.spyOn(console, "log");
    const mResponse = "send mail success";
    sgMail.send.mockResolvedValueOnce(mResponse);
    simplemail();
    setImmediate(() => {
      expect(sgMail.send).toBeCalledWith({
        to: "receiver@mail.com",
        from: "sender@test.com",
        subject: "TEST Sendgrid with SendGrid is Fun",
        text: "and easy to do anywhere, even with Node.js",
        html: "<strong>and easy to do anywhere, even with Node.js</strong>",
        mail_settings: {
          sandbox_mode: {
            enable: true
          }
        }
      });
      expect(logSpy).toBeCalledWith(mResponse);
      done();
    });
  });

  it("should print error when send email failed", done => {
    const errorLogSpy = jest.spyOn(console, "error");
    const mError = new Error("network error");
    sgMail.send.mockRejectedValueOnce(mError);
    simplemail();
    setImmediate(() => {
      expect(sgMail.send).toBeCalledWith({
        to: "receiver@mail.com",
        from: "sender@test.com",
        subject: "TEST Sendgrid with SendGrid is Fun",
        text: "and easy to do anywhere, even with Node.js",
        html: "<strong>and easy to do anywhere, even with Node.js</strong>",
        mail_settings: {
          sandbox_mode: {
            enable: true
          }
        }
      });
      expect(errorLogSpy).toBeCalledWith(mError.toString());
      done();
    });
  });
});

Unit test result with 100% coverage:

 PASS  src/stackoverflow/59108624/index.spec.js (6.954s)
  #sendingmailMockedway
    ✓ Should send mail with specefic value (9ms)
    ✓ should print error when send email failed (17ms)

  console.log node_modules/jest-mock/build/index.js:860
    send mail success

  console.error node_modules/jest-mock/build/index.js:860
    Error: network error

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.336s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59108624



来源:https://stackoverflow.com/questions/59108624/test-sendgrid-implementation-with-jest-and-mock-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!