Adrian
Adrian

Reputation: 9660

Trying to stub a method used inside a Node module

I'm trying to mock a function inside a Node module. But it doesn't allow me. Any ideas?

// module A

function foo(){
  return 1;
}

function bar(){
   return foo() + 1;
}

module.exports = {foo, bar}

In the test...

const a = require('a');
...
sinon.stub(a, 'foo').callsFake(() => 3);
expect(a.bar()).to.equal(4); // gets 2 instead of 4

Upvotes: 0

Views: 621

Answers (1)

Dylan Aspden
Dylan Aspden

Reputation: 1692

Due to the way Sinon stubs a function in a module you actually end up with an interesting situation. Your function is actually being stubbed but is being stubbed only at module.exports.foo. Your original function foo is unchanged. Basically what Sinon does is that it wraps your module.exports.{function} with their special functionalities.

If you want to have any stubs persist in your bar function you need to reference foo on the exports object and not directly.

function bar() {
  return module.exports.foo() + 1;
}

Good luck :)

EDIT: Usually when I want to do things like this I write my modules and use their functions this way...

// module A

exports.foo = function foo() {
  return 1;
}

exports.bar = function bar() {
  return exports.foo() + 1;
}

That way if anything in the module gets stubbed / mocked / spied it will apply to all other calls inside of the module. But in general my recommendation is if you plan to ever plan to stub a function you never want to reference it directly from anywhere. You need to reference those functions through an object so that Sinon can perform the replacement on the object.

Upvotes: 5

Related Questions