javascriptnode.jsunit-testingrequireproxyquire

Mocking a nested module in Node.js?


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()?


Solution

  • 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.