Node.js Tests using Mocha

In this post, I want to talk a little more about basic Mocha tests. Here are two tests in my mail.service.test file:


var mail = require('app/services/mail.service');
var config = require('../../config/config');
var should = require('should');

describe('Send Mail', function() {

it('should send a valid email via SMTP and return true', function(done) {
config.useMailer = 'SMTP';
config.requireModules.nodemailer.sendMailError = false;
mail.sendMail(config.testMailer.FromAddress, config.testMailer.ToAddresses,config.testMailer.subject, config.testMailer.body, function(res) {
res.should.be.true;
});
done();
});

it('should fail via SMTP when the mail service encounters an error', function(done) {
config.useMailer = 'SMTP';
config.requireModules.nodemailer.sendMailError = true;
mail.sendMail(config.testMailer.FromAddress, config.testMailer.ToAddresses,config.testMailer.subject, config.testMailer.body, function(res) {
res.should.be.false;
});
done();
});
});

Very roughly, the ‘describe’ is sort of equivalent to a Gherkin ‘feature’, while ‘it’ is sort of equivalent to a Gherkin scenario, even though cucumber and Mocha work in entirely different ways.

Let’s look at the first test in more detail. My app can use multiple mailing methods. config.useMailer = ‘SMTP’ just chooses the SMTP method. I’ll show you the simplified module in a bit. config.requireModules.nodemailer.sendMailError = false is only used by my mock mailer. Note in the second test it’s set to true, which merely forces the mock mailer to return an error no matter what it’s passed. The mail.sendMail(…) is the actual attempt to send an email. That’s it for the test.

Here’s a simplified version of my mail service:


var config = require('../../config/config');
var log = require('npmlog');

var nodemailer = require(config.requireModules.nodemailer.version);

exports.sendMail = function(mail_from, mail_to, mail_subject, mail_body) {
var status = false;
if (config.useMailer === 'SMTP') {
var smtpTransport = nodemailer.createTransport(config.mailer.options);
var mailOptions = {
to: mail_to,
from: mail_from,
subject: mail_subject,
html: mail_body
};
smtpTransport.sendMail(mailOptions, function(error, info) {
if (error) {
log.error('error sending email via SMTP to:' + mail_to + ' about ' + mail_subject + '\nError: ' + error + '\n\n\n');
status = false;
} else {
log.info('email sent via SMTP to:' + mail_to + ' about ' + mail_subject + ' info: ' + info.response + '\n\n\n');
status = true;
};
});
}
return status;
};

Look at the top: var nodemailer = require(config.requireModules.nodemailer.version);

This pulls the name of the module to require out of the config file. For testing, I put the mock module name in the config file. For testing, I have a mock nodemailer module and set the path to it in the config file. I posted about this earlier.

The mock nodemailer looks like this:


var config = require('config/config');

module.exports.createTransport = function(transporter) {
return new Nodemailer(transporter);
};

function Nodemailer(transporter) {
this.mock = 'Mock-Nodemailer!';
this.transporter = transporter;
};

Nodemailer.prototype.sendMail = function(data, callback) {
callback = callback || function() {};
var info = {};
var error;
if (config.requireModules.nodemailer.sendMailError) {
info.response = 'ERROR';
error = true;
} else {
info.response = 'OK';
error = null;
}
return callback(error, info);
};

So, these two tests ensure that both of the condition branches (ie: the error check in the sendMail callback) get tested and the correct response code is returned.

Advertisements

About jeffmershon

Director of Program Management at SiriusXM.
This entry was posted in Software, Uncategorized and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s