Reputation: 1818
I need to stub the sendMandrill method of the mh object.
See my file under test (mail.js):
let MailHandler = require('../../modules/mail.handler.module');
...
let api = (router, parser) => {
let send = async (req, res, next) => {
let mh = new MailHandler();
mh.sendMandrill();
...
}
...
return router.post('/mail/send', parser.json(), send);
}
module.exports = api;
...
My test (mail.spec.js):
let stRequest = require('supertest');
let MailHandler = require('../../modules/mail.handler.module');
describe('my test', () => {
beforeEach(() => {
sinon.stub(MailHandler.prototype, 'sendMandrill', () => true);
})
it('stubs sendMandrill!', done => {
stRequest(app)
.post('/mail/send')
.end((err, resp) => {
done();
});
})
})
Currently I'me getting the error below:
TypeError: Cannot stub non-existent own property sendMandrill
Adding mail.handler.module - See below the mailHandler / sendMandrill code:
module.exports = mailHandler;
function mailHandler() {
...
var mandrill = require('../modules/mandrill');
var handler = {
sendMandrill: sendMandrill,
...
};
return handler;
function sendMandrill() {
mandrill.messages.sendTemplate({
message: {...}
});
}
...
}
Upvotes: 0
Views: 2563
Reputation: 45121
You current approach creates a new sendMandrill
for each and every instance created by mailHandler
factory. You should actually call it w/o new let mh = mailHandler()
or even better rename it to createMailHandler
to avoid misuse.
If you want to effectively use prototype inheritance you'll need to rewrite mailHandler
to use actually use this
instead of a newly created object.
var mandrill = require('../modules/mandrill');
module.exports = MailHandler;
function MailHandler() {
// use this instead of newly created object
this.foo = 'bar'
// avoid explicit return
// return handler;
}
// set methods to prototype
MailHandler.prototype.sendMandrill = function sendMandrill() {
// use this instead of handler here
mandrill.messages.sendTemplate({
message: {...}
});
}
Using the above approach you would be able to stub prototype properties via sinon
and justify calling the constructor with new
keyword.
UPD
If you have no control over mail.handler.module
you could either use rewire
module that allows to mock entire dependencies or expose MailHandler
as a part of your api
module to make it injectable.
api.MailHandler = require('../../modules/mail.handler.module')
let mh = api.MailHandler();
And then in tests
let oldMailHandler;
beforeAll(() => { oldMailHandler = api.MailHandler})
afterAll(() => { api.MailHandler = oldMailHandler})
beforeEach(() => { api.MailHandler = function MockMailHandler() {} })
Upvotes: 1