在 Node.js 中使用 Jest 和 Mock 测试 Sendgrid 实现

1 unit-testing mocking node.js sendgrid jestjs

我在我的nodejs应用程序中使用sendGrid电子邮件,我想用jest测试它。

这是我的应用程序代码:

邮件.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;
Run Code Online (Sandbox Code Playgroud)

这是我用玩笑测试它所做的事情:

邮件测试.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',
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

我需要修复此文件上的代码覆盖率,以便进行尽可能多的测试,并测试邮件是否已发送并捕获是否有错误或现在,这就是我在 mail.js 中添加的原因

mail_settings: {
  sandbox_mode: {
    enable: true,
  },
},
Run Code Online (Sandbox Code Playgroud)

我想用 jest 和模拟 sendgrid 来测试它,但如何测试呢?

sli*_*wp2 6

因为您使用 IIFE 并async/awaitsimplemail函数中使用setImmediate在单元测试用例中断言 IIFE 之前,请使用函数来确保执行 IIFE。

\n\n

这是单元测试解决方案:

\n\n

index.js:

\n\n
const sgMail = require("@sendgrid/mail");\nsgMail.setApiKey(process.env.SENDGRID_API_KEY);\n\nconst simplemail = () => {\n  const msg = {\n    to: "receiver@mail.com",\n    from: "sender@test.com",\n    subject: "TEST Sendgrid with SendGrid is Fun",\n    text: "and easy to do anywhere, even with Node.js",\n    html: "<strong>and easy to do anywhere, even with Node.js</strong>",\n    mail_settings: {\n      sandbox_mode: {\n        enable: true\n      }\n    }\n  };\n  (async () => {\n    try {\n      console.log(await sgMail.send(msg));\n    } catch (err) {\n      console.error(err.toString());\n    }\n  })();\n};\n\nexport default simplemail;\n
Run Code Online (Sandbox Code Playgroud)\n\n

index.spec.js:

\n\n
import simplemail from "./";\nconst sgMail = require("@sendgrid/mail");\n\njest.mock("@sendgrid/mail", () => {\n  return {\n    setApiKey: jest.fn(),\n    send: jest.fn()\n  };\n});\n\ndescribe("#sendingmailMockedway", () => {\n  afterEach(() => {\n    jest.resetAllMocks();\n    jest.restoreAllMocks();\n  });\n  it("Should send mail with specefic value", done => {\n    const logSpy = jest.spyOn(console, "log");\n    const mResponse = "send mail success";\n    sgMail.send.mockResolvedValueOnce(mResponse);\n    simplemail();\n    setImmediate(() => {\n      expect(sgMail.send).toBeCalledWith({\n        to: "receiver@mail.com",\n        from: "sender@test.com",\n        subject: "TEST Sendgrid with SendGrid is Fun",\n        text: "and easy to do anywhere, even with Node.js",\n        html: "<strong>and easy to do anywhere, even with Node.js</strong>",\n        mail_settings: {\n          sandbox_mode: {\n            enable: true\n          }\n        }\n      });\n      expect(logSpy).toBeCalledWith(mResponse);\n      done();\n    });\n  });\n\n  it("should print error when send email failed", done => {\n    const errorLogSpy = jest.spyOn(console, "error");\n    const mError = new Error("network error");\n    sgMail.send.mockRejectedValueOnce(mError);\n    simplemail();\n    setImmediate(() => {\n      expect(sgMail.send).toBeCalledWith({\n        to: "receiver@mail.com",\n        from: "sender@test.com",\n        subject: "TEST Sendgrid with SendGrid is Fun",\n        text: "and easy to do anywhere, even with Node.js",\n        html: "<strong>and easy to do anywhere, even with Node.js</strong>",\n        mail_settings: {\n          sandbox_mode: {\n            enable: true\n          }\n        }\n      });\n      expect(errorLogSpy).toBeCalledWith(mError.toString());\n      done();\n    });\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

100%覆盖率的单元测试结果:

\n\n
 PASS  src/stackoverflow/59108624/index.spec.js (6.954s)\n  #sendingmailMockedway\n    \xe2\x9c\x93 Should send mail with specefic value (9ms)\n    \xe2\x9c\x93 should print error when send email failed (17ms)\n\n  console.log node_modules/jest-mock/build/index.js:860\n    send mail success\n\n  console.error node_modules/jest-mock/build/index.js:860\n    Error: network error\n\nTest Suites: 1 passed, 1 total\nTests:       2 passed, 2 total\nSnapshots:   0 total\nTime:        8.336s\n
Run Code Online (Sandbox Code Playgroud)\n\n

源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59108624

\n