5

I have these files:

File1.js

var mod1 = require('mod1');
mod1.someFunction()
...

File2.js

var File1 = require('./File1');

Now while writing unit tests for File2, is it possible to have mod1 mocked, so that I don't make calls to mod1.someFunction()?

4
  • 2
    Yes it is possible. You should read something about dependency injection. And have a look at sinon.js. Commented Feb 1, 2016 at 19:44
  • Take a look at this tutorial on mocking: youtube.com/watch?v=fgqh-OZjpYY It shows a technique you can use just for this. And yeah, definitely check out sinon. Commented Feb 1, 2016 at 19:48
  • how will sinon address this? Commented Feb 1, 2016 at 19:49
  • Sinon helps with creating stubs for the functions being created, so that it's easy to verify whether they were called correctly, return the correct values, etc. Commented Feb 4, 2016 at 3:01

2 Answers 2

5

I'm usually using mockery module like following:

lib/file1.js

var mod1 = require('./mod1');
mod1.someFunction();

lib/file2.js

var file1 = require('./file1');

lib/mod1.js

module.exports.someFunction = function() {
  console.log('hello from mod1');
};

test/file1.js

/* globals describe, before, beforeEach, after, afterEach, it */

'use strict';

//var chai = require('chai');
//var assert = chai.assert;
//var expect = chai.expect;
//var should = chai.should();

var mockery = require('mockery');

describe('config-dir-all', function () {

  before('before', function () {
    // Mocking the mod1 module
    var mod1Mock = {
      someFunction: function() {
        console.log('hello from mocked function');
      }
    };

    // replace the module with mock for any `require`
    mockery.registerMock('mod1', mod1Mock);

    // set additional parameters
    mockery.enable({
      useCleanCache:      true,
      //warnOnReplace:      false,
      warnOnUnregistered: false
    });
  });

  beforeEach('before', function () {

  });

  afterEach('after', function () {

  });

  after('after', function () {
    // Cleanup mockery
    after(function() {
      mockery.disable();
      mockery.deregisterMock('mod1');
    });
  });

  it('should throw if directory does not exists', function () {

    // Now File2 will use mock object instead of real mod1 module
    var file2 = require('../lib/file2');

  });

});

As it was suggested before, sinon module is very convenient to build the mocks.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that worked! I was actually trying Mockery before, but had the name of the mock in quotes, and didn't realize.
Hmm.. didn't work for me. Not sure why. Maybe because the nested require is using relative path for require?
2

Absolutely. There are 2 very popular node.js libraries exclusively for the purpose of mocking requires.

https://github.com/jhnns/rewire

https://github.com/mfncooper/mockery

Both of them have different API, and rewire has some strange caveats

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.