问题
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