0

I have a function for which I am writing unit test but that function is calling another function and there I am not able to mock/stub that function.

for example :

function getValue( param1, param2, callback){
    getData(param1, param3).then( response) => {
         return callback();
    }, (err) => {
         return callback();
    });
}

So I don't know how to mock getData() function.

7
  • Where is getData defined ? Commented Apr 1, 2019 at 6:15
  • getData is defined in some other file which I am importing. Commented Apr 1, 2019 at 6:21
  • Then ask the question accordingly, There's no way to mock getData if it's random function, only it's an import. Commented Apr 1, 2019 at 6:25
  • Just to be complete, it is possible to mock getData even if it is a random function in the same file, but it must be exported and it must be called using the module export. (See this answer for an ES6 version, a Node.js module would export getData like this: exports.getData = getData; and then call it within getValue like this: exports.getData(...)) Commented Apr 1, 2019 at 7:14
  • hey @brian-lives-outdoors getData is being exported. Commented Apr 1, 2019 at 19:43

2 Answers 2

1

Here is a working example that demonstrates what you are trying to do:

lib.js

function getData(param1, param2) {
  return fetch('someUrl');  // <= something that returns a Promise
}

exports.getData = getData;

code.js

const lib = require('./lib');

export function getValue(param1, param2, callback) {
  return lib.getData(param1, param2).then(response => {
    callback(response);
  }).catch(err => {
    callback(err);
  });
}

exports.getValue = getValue;

code.test.js

const sinon = require('sinon');

const lib = require('./lib');
const { getValue } = require('./code');

describe('getValue', () => {
  it('should do something', async () => {
    const stub = sinon.stub(lib, 'getData');
    stub.resolves('mocked response');

    const callback = sinon.spy();
    await getValue('val1', 'val2', callback);

    sinon.assert.calledWithExactly(stub, 'val1', 'val2');  // Success!
    sinon.assert.calledWithExactly(callback, 'mocked response');  // Success!
  });
});

Update

OP added in the comments that they can't use async / await and are exporting the function using module.exports = getData;.

In that case the module export is the function and the entire module needs to be mocked with something like proxyquire.

The assertions should be done in a then callback and the test should return the resulting Promise so mocha knows to wait for it to resolve.

Updated example:

lib.js

function getData(param1, param2) {
  return fetch('someUrl');  // <= something that returns a Promise
}

module.exports = getData;

code.js

const getData = require('./lib');

function getValue(param1, param2, callback) {
  return getData(param1, param2).then(response => {
    callback(response);
  }).catch(err => {
    callback(err);
  });
}

module.exports = getValue;

code.test.js

const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('getValue', () => {
  it('should do something', () => {
    const stub = sinon.stub();
    stub.resolves('mocked response');

    const getValue = proxyquire('./code', { './lib': stub });

    const callback = sinon.spy();
    return getValue('val1', 'val2', callback).then(() => {
      sinon.assert.calledWithExactly(stub, 'val1', 'val2');  // Success!
      sinon.assert.calledWithExactly(callback, 'mocked response');  // Success!
    });
  });
});
Sign up to request clarification or add additional context in comments.

4 Comments

Hey I am using module.exports = getData also async() is not working in node js 6 and as of now it is throwing following error TypeError: Cannot stub non-existent own property getData. Please respond . Thanks
I added an update with an example that works with those constraints. @ankuselfie
TypeError: Cannot read property 'then' of undefined this what I am getting. Also actual function is being called.
hey @brian-lives-outdoors this is not working, it is still not stubbing 'getData` function. Thanks :)
0
function getValue( param1, param2, callback){
    getData(param1, param3).then( response) => {
         callback(response);
    });
}

getvalue(param1, param2, function(error, response)) {
   console.log(response)
}

It might help you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.