Muhammad Aadil Banaras
Muhammad Aadil Banaras

Reputation: 1284

stub a function with callback, don't return promise

I have a service which is calling a function, I am writing a test for that service and I need to stub the function inside that service, that function has callback instead of returning a promise. when I make the stub for that I and give dummy return but it hangs as service expects the callback, here is my code for the test

describe('Testing Token Service', () => {
let _stub =null;
beforeEach(async()=>{
    _stub = sinon.stub(tModel.prototype, "save")
})
afterEach(async()=>{
  if(_stub){
    _stub.restore()
  }
})

it('testing function saveToken_mongo() ', (done) => {
    _stub.returns(Promise.resolve( {'status' : 'true'} ))
    token_service.saveToken_mongo({},function(err, data){
        console.log(err, data)
        done();
    })
    // done()
});   });

and here is the service function for which I am writing test

Service.prototype.saveToken_mongo = function(token, callback){
var _token = new tModel( token ) ;
_token.save(function(err, data){
    if(err){
        callback(err, null);
        return ;
    }
    else{
        callback(null, {'status':true})
        return ;
    }  
}) }

I need to make dummy callback return from that function using stub.

Upvotes: 0

Views: 617

Answers (3)

Muhammad Aadil Banaras
Muhammad Aadil Banaras

Reputation: 1284

After the study, I reached the conclusion that there are 2 solutions to this problem.

1) according to deerawan we can use yields to replace callback of function, like this

_stub.yields(null, {'status' : 'true'});

for more detail https://sinonjs.org/releases/v7.1.1/stubs/#stubyieldsarg1-arg2-

2) use bluebird to promisify all methods which will change all methods response from the callback to promise then you can use Promise.returns, here is code

var Model = conn.model( name , ModelSchema);
var Promise = require('bluebird');
Promise.promisifyAll(Model);
Promise.promisifyAll(Model.prototype);
module.exports = Model;

Now you can use test as follows

let _stub = null;
var tModel = require('./../app/models/tokens') ;
beforeEach(async()=>{
    _stub = sinon.stub(tModel.prototype, "save")
})
afterEach(async()=>{
  if(_stub){
    _stub.restore()
  }
})
it('returns a Promise' ,async function(){
    _stub.returns(Promise.resolve( {'status' : 'true & false'} ));
    expect(token_service.saveToken_mongo({})).to.be.a("Promise")   
})

Upvotes: 0

deerawan
deerawan

Reputation: 8443

stub.returns is used for ordinary function not for callback. Since save is callback function, we can use yields.

_stub.yields(null, {'status' : 'true'});

The first argument is for error value, and the second one is for data.

As reference:

https://sinonjs.org/releases/v7.1.1/stubs/#stubyieldsarg1-arg2-

Upvotes: 1

Shay Moshe
Shay Moshe

Reputation: 482

It's a bit tricky, your callback is the saveToken_mongo param,

didn't test it but try:

 _stub.returns(function(err, data){callback(null, {'status':true}) });

let me know if you got an error for the callback, you may try using this.callback instead

Upvotes: 0

Related Questions