I want to unit test a function in my sails.js application using Mocha(test framework) and Sinon(test double library). This is how the function under test looks like
function saveNotifications(notificationData, cb){
checkForDuplicates(notificationData, (err, isDuplicate) => {
if(isDuplicate) return updateNotification(notificationData, (err, updatedData)=> { cb(err, updatedData) })
// No duplicate exists, so save the notification in db
Notification.create(notification).exec((err, savedData) => {
return cb(err, savedData)
})
})
})
Although I was able to fake checkForDuplicates
and add some tests for that. But when I wanted to stub(or fake) Notification.create(notification).exec
method in order to check if create method was called once for particular test case, I was not able to figure out how to do that. Neither do I understand how to stub chained methods nor am I able to stub simple Notification.create
object itself. I am assuming some gaps in my understanding of how to stub waterline method instances. Appreciate any help/advice.
What I have tried
I tried to do simpler things first i.e. stubbing create method
it('#saveNotifications({userId: "1", message: "Test message"}, cb)', (done) => {
sinon.stub(Notification, 'create');
saveNotifications({userId: "1", message: "Test message"}, (err, result) => {
try {
expect(err).to.not.throw;
expect(err).to.be.null;
expect(result).to.be.not.null;
sinon.assert.calledOnce(Notification.create);
sinon.restore();
done();
} catch(e){
sinon.restore();
done(e);
}
})
but this gives error
TypeError: Cannot stub non-existent property create
CodePudding user response:
There are two issues you mentioned, let's sort them out one by one
- Stub simple Notification.create object?
You have already written the right code for this but you are not referencing the correct model object. Instead of Notification
object, use sails.models.notification
i.e.
sinon.stub(sails.models.notification, 'create')
- How to stub chained methods
Fake the returned value and use stub in the returned function i.e.
sinon.stub(sails.models.notification, 'create').callsFake(function(){
return {
exec: theStubbedChainFunction
}
})
var theStubbedChainFunction = sinon.stub().yields(null, { id: '1', message: 'canned response'})
// Then you can assert to test
sinon.assert.calledOnce(theStubbedChainFunction)
If you had more chained function (e.g. Notification.update(criteria).set(valuedToUpdate).fetch().exec(function(err, updatedRecords){...})
, you could follow the same principal e.g.
sinon.stub(sails.models.notification, 'update').callsFake(function(){
return {
set: sinon.stub().callsFake(function(){
return {
fetch: sinon.stub().callsFake(function(){
exec: theStubbedChainFunction
})
}
})
}
})