nodemailer-mock
Easy as pie nodemailer
mock for unit testing your Node.js applications.
install
npm install nodemailer-mock --save-dev
yarn add -D nodemailer-mock
mock api
Use with test suites like jest
and mocha
. There are some special methods available on the mocked module to help with testing. They are under the .mock
key of the mocked nodemailer
.
nodemailerMock.mock.reset()
- resets the mock class to default values
nodemailerMock.mock.getSentMail()
- returns an array of sent emails during your tests, since the last reset
nodemailerMock.mock.setShouldFailOnce()
- will return an error on the next call to
transport.sendMail()
nodemailerMock.mock.setShouldFail({boolean} shouldFail)
- indicate if errors should be returned for subsequent calls to
transport.sendMail()
- if
true
, return error - if
false
, return success
nodemailerMock.mock.setShouldFailCheck({Function} (email)=>{})
- indicate if the specific email passed to the function should fail the call to
transport.sendMail()
- if function returns
true
, return error - if function returns
false
, return success
nodemailerMock.mock.setMockedVerify({boolean} isMocked)
- determine if a call to
transport.verify()
should be mocked or passed through to nodemailer
- if
true
, use a mocked callback - if
false
, pass through to a real nodemailer
transport
- Note that this will not work with
jest
as all nodemailer
instances are mocked
nodemailerMock.mock.setSuccessResponse({Mixed} success)
- set the success message that is returned in the callback for
transport.sendMail()
nodemailerMock.mock.setFailResponse({Error} err)
- set the
Error
that is returned in the callback for transport.sendMail()
Note that the .mock
methods in previous versions are aliased to the new names.
Version 1.5+ returns an Error
object on error rather than a string.
usage
The mocked module behaves in a similar fashion to other transports provided by nodemailer
.
setup test
const nodemailerMock = require('nodemailer-mock');
const transport = nodemailerMock.createTransport();
const email = ...
use nodestyle callbacks
transport.sendMail(email, function(err, info) {
if (err) {
return console.log('Error!', err, info);
}
return console.log('Success!', info);
}
transport.verify(function(err, success) {
if (err) {
return console.log('Error!', err);
}
return console.log('Success!', success);
});
use promises
transport.sendMail(email)
.then(function(info) {
console.log('Success!', info);
})
.catch(function(err) {
console.log('Error!', err);
});
transport.verify()
.then(function(success) {
console.log('Success!', success);
});
.catch(function(err) {
console.log('Error!', err);
});
use async/await
try {
const info = await transport.sendMail(email);
} catch (err) {
console.log('Error!', err);
}
try {
const info = await transport.verify();
} catch (err) {
console.log('Error!', err);
}
example tests using mocked module
To use nodemailer-mock
in your tests you will need to mock nodemailer
with it. There are working examples using jest
and jest
in the ./examples/
folder of the project. The jest
code is in ./examples/__mocks__
and ./examples/__tests__
, and the mocha
tests are in ./examples/test
. You will need to npm i -D jest
and/or npm i -D mockery
to run the examples, and with a shortcut of npm run example:jest
and npm run example:mocha
.
example using jest
To mock nodemailer
using jest
create a file called ./__mocks__/nodemailer.js
that exports the mocked module:
module.exports = require('nodemailer-mock');
Once the mock file is created all calls to nodemailer
from your tests will return the mocked module. To access to mock functions, just load it in your test file. Note that transport.verify()
passthrough is not available as the module is mocked before nodemailer-mock
is loaded so it can't be accessed.
const { mock } = require('nodemailer');
test('Send an email using the mocked nodemailer', async () => {
const sentEmails = mock.getSentMail();
expect(sentEmails.length).toBe(1);
expect(sentEmails[0].to).toBe('justin@to.com');
});
example using mocha and mockery
Here is an example of using a mocked nodemailer
class in a mocha
test using mockery
. Make sure that any modules that require()
's a mocked module must be called AFTER the module is mocked or node will use the unmocked version from the module cache. Note that this example uses async/await
. See the module tests for additional example code.
const should = require('should');
const mockery = require('mockery');
const nodemailerMock = require('nodemailer-mock');
describe('Tests that send email', async () {
let app = null;
before(async () {
mockery.enable({
warnOnUnregistered: false,
});
mockery.registerMock('nodemailer', nodemailerMock)
const someModuleThatRequiresNodemailer = require('some-module-that-requires-nodemailer');
});
afterEach(async () {
nodemailerMock.mock.reset();
});
after(async () {
mockery.deregisterAll();
mockery.disable();
});
it('should send an email using nodemailer-mock', async () {
const response = ...
response.value.should.be.exactly('value');
const sentMail = nodemailerMock.mock.getSentMail();
sentMail.length.should.be.exactly(1);
sentMail[0].property.should.be.exactly('foobar');
});
it('should fail to send an email using nodemailer-mock', async () {
const err = new Error('My custom error');
nodemailerMock.mock.setShouldFailOnce();
nodemailerMock.mock.setFailResponse(err);
var response = ...
response.error.should.be.exactly(err);
});
it('should verify using the real nodemailer transport', async () {
nodemailerMock.mock.setMockedVerify(false);
var response = ...
});
});