Stub function called by other function in the same module

3,965 views
Skip to first unread message

Nuruddin Ashr

unread,
Aug 5, 2015, 2:57:32 AM8/5/15
to Sinon.JS
Hi Guys, need help here.
It seems stubbing function is not working if the function called by other function on the same module.

Given module
users.js
function authenticateOk(username, password) {
  var user = findByUsername(username);
  return (user != null && user.password === password);
}

function findByUsername(username) {
  return null;
}

module.exports.authenticateOk = authenticateOk;
module.exports.findByUsername = findByUsername;


users_test.js
var sinon = require('sinon');
var assert = require('assert');
var users = require('./users');

var user = {
  username: 'uudashr',
  password: 'uudashr123'
};

var findByUsernameStub = sinon.stub(users, 'findByUsername');
findByUsernameStub.returns(user);

var returnedUser = users.findByUsername(user.username);
assert(returnedUser != null, '#findByUsername should return non null user');

var result = users.authenticateOk(user.username, user.password);
assert(result, '#authenticateOk should return true');

findByUsernameStub.restore();


The second assert will failed. 
Except I change the invocation of "#findByUsername" on the users.js become like this:
...
function authenticateOk(username, password) {
  var user = module.exports.findByUsername(username);
  return (user != null && user.password === password);
}
...

It works but invoking method using module.exports.findByUsername(..) seems lil bit uncommon. Because it require code style changes.
Is that the only way or there is a better way?

Thanks,
Uud

Travis Kaufman

unread,
Aug 5, 2015, 6:25:26 AM8/5/15
to Sinon.JS
Stubbing a method on an object does not alter the method definition itself, but instead simply overwrites the value of the specified property to be a stub function. Because of this, using the findByUsername function inside another method will not invoke the stubbed function because that is simply assigned to module.exports.findByUsername. If you want to actually override the value of a function defined inside a module, I've found that rewire works well for this. 

--
You received this message because you are subscribed to the Google Groups "Sinon.JS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sinonjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nuruddin Ashr

unread,
Aug 6, 2015, 5:06:37 AM8/6/15
to Sinon.JS
Thanks for the response.

I got other solution here by treat the module as object.
module.exports = {
  authenticateOk: function(username, password) {
    var user = this.findByUsername(username);
    return (user != null && user.password === password);
  },
  findByUsername: function(username) {
    return null;
  }
};

or 

var findByUsername = function(username) {
  return null;
};

function authenticateOk(username, password) {
  var user = this.findByUsername(username);
  return (user != null && user.password === password);
}

module.exports.authenticateOk = authenticateOk;
module.exports.findByUsername = findByUsername;

I think this is the only one way to use Sinon without "rewire" by create the module/code become testable.
Reply all
Reply to author
Forward
0 new messages