Home > Net >  How to unit test waterline model create method instance
How to unit test waterline model create method instance

Time:10-31

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

  1. 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')

  1. 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
                      })
                   }
         })
  }
})
  • Related