Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sinon stub not replacing function

I'm trying to use sinon stub to replace a function that might take along time. But when I run the tests, the test code doesn't seem to be using the sinon stubs.

Here is the code I'm trying to test.

function takeTooLong() {
    return  returnSomething();
}

function returnSomething() {
    return new Promise((resolve) => {
        setTimeout(() => {
          resolve('ok')
        }, 1500)
    })
}

module.exports = {
  takeTooLong,
  returnSomething
}

and this is the test code.

const chai = require('chai')
chai.use(require('chai-string'))
chai.use(require('chai-as-promised'))
const expect = chai.expect
chai.should()
const db = require('./database')
const sinon = require('sinon')
require('sinon-as-promised')

describe('Mock the DB connection', function () {

it('should use stubs for db connection for takeTooLong', function (done) {

    const stubbed = sinon.stub(db, 'returnSomething').returns(new Promise((res) => res('kk')));
    const result = db.takeTooLong()

    result.then((res) => {

        expect(res).to.equal('kk')
        sinon.assert.calledOnce(stubbed);
        stubbed.restore()
        done()
    }).catch((err) => done(err))

})

I get an assertion error

 AssertionError: expected 'ok' to equal 'kk'
      + expected - actual

  -ok
  +kk

What am I doing wrong? Why isn't the stub being used ? The test framework in Mocha.

like image 305
AshanPerera Avatar asked Nov 25 '16 12:11

AshanPerera


People also ask

How do you stub a function in Sinon?

The sinon. stub() substitutes the real function and returns a stub object that you can configure using methods like callsFake() . Stubs also have a callCount property that tells you how many times the stub was called. For example, the below code stubs out axios.

How do I reset my Sinon stub?

var stub = sinon. The original function can be restored by calling object. method. restore(); (or stub. restore(); ).

How do you stub a dependency of a module?

To stub a dependency (imported module) of a module under test you have to import it explicitly in your test and stub the desired method. For the stubbing to work, the stubbed method cannot be destructured, neither in the module under test nor in the test.

How do you stub a promise in Sinon?

To stub a promise with sinon and JavaScript, we can return a promise with a stub. import sinon from "sinon"; const sandbox = sinon. sandbox. create(); const promiseResolved = () => sandbox.


2 Answers

Sinon stubs the property of the object, not the function itself.

In your case you are exporting that function within an object.

module.exports = {
  takeTooLong,
  returnSomething
}

So in order to properly call the function from the object, you need to replace your function call with the reference to the export object like :

function takeTooLong() {
    return module.exports.returnSomething();
}

Of course based on your code, you can always refactor it :

var exports = module.exports = {

    takeTooLong: function() { return exports.returnSomething() }

    returnSomething: function() { /* .. */ }

}
like image 167
drinchev Avatar answered Sep 21 '22 06:09

drinchev


You might want to have a look at Proxyquire to stub/spy directly exported functions. https://www.npmjs.com/package/proxyquire/

like image 37
Aaditya Chakravarty Avatar answered Sep 18 '22 06:09

Aaditya Chakravarty