Posted on April 15, 2014 by Chris Harrington

Stubbing included functions with Sinon while unit testing in Node

I’ve recently been on a unit testing bender with Leaf; I was able to get to 100% code coverage. I understand that while I might have 100% coverage, I might also have shitty tests, but I feel the inverse is also true: if I have 0% coverage, I most definitely have shitty tests. Either way, I ran into a few hurdles while writing all of these unit tests and I’d like to share how I got around one of them in particular. Most of the libraries that I require in Leaf expose a number of methods for me to use, which is great, because they’re easy to stub using Sinon, as such:

var getStub = sinon.stub(obj, "get");

Unfortunately, not every library follows this standard. Leaf uses SendGrid to send emails for notifications, user registrations, etc. The required SendGrid package exposes a function to which you’re supposed to provide your credentials:

var sendgrid = require("sendgrid")("your sendgrid username", "your sendgrid password");

This works fine until you want to run some unit tests against a class that uses SendGrid. What do you stub? There’s no object that SendGrid exposes to stub. I got around this by making use of the “call” method. Instead of invoking the SendGrid package’s root function normally, I “call” it. JavaScript’s call method is ostensibly used to change the value of the context when inside the function; it modifies the value of “this”. I’m not using it for that here, but it works well enough for our purposes.

var sendgrid = require("sendgrid").call(this, "your sendgrid username", "your sendgrid password");

Invoking the function this way lets us stub the “call” method and keep track of the result, like so:

var sendgrid = sinon.stub(require("sendgrid"), "call").returns();

It’s not a perfect solution, as you have to modify the code you’re testing to provide support for mocks and stubs, but it’s better than nothing.