Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stub require() / expect calls to the "root" function of a module?

Consider the following jasmine spec:

describe("something.act()", function() {
  it("calls some function of my module", function() {
    var mod = require('my_module');
    spyOn(mod, "someFunction");
    something.act();
    expect(mod.someFunction).toHaveBeenCalled();
  });
});

This is working perfectly fine. Something like this makes it green:

something.act = function() { require('my_module').someFunction(); };

Now have a look at this one:

describe("something.act()", function() {
  it("calls the 'root' function of my module", function() {
    var mod = require('my_module');
    spyOn(mod); // jasmine needs a property name
                // pointing to a function as param #2
                // therefore, this call is not correct.
    something.act();
    expect(mod).toHaveBeenCalled(); // mod should be a spy
  });
});

This is the code I'd like to test with this spec:

something.act = function() { require('my_module')(); };

This has bogged me down several times in the last few months. One theoretical solution would be to replace require() and return a spy created with createSpy(). BUT require() is an unstoppable beast: it is a different "copy" of the function in each and every source file/module. Stubbing it in the spec won't replace the real require() function in the "testee" source file.

An alternative is to add some fake modules to the load path, but it looks too complicated to me.

Any idea?

like image 989
jbpros Avatar asked Aug 09 '11 14:08

jbpros


1 Answers

rewire is awesome for this

var rewire = require('rewire');

describe("something.act()", function() {
  it("calls the 'root' function of my module", function() {
    var mod = rewire('my_module');
    var mockRootFunction = jasmine.createSpy('mockRootFunction');
    var requireSpy = {
      mockRequire: function() {
        return mockRootFunction;
      }
    };
    spyOn(requireSpy, 'mockRequire').andCallThrough();

    origRequire = mod.__get__('require');
    mod.__set__('require', requireSpy.mockRequire);

    something.act();
    expect(requireSpy.mockRequire).toHaveBeenCalledWith('my_module');
    expect(mockRootFunction).toHaveBeenCalled();

    mod.__set__('require', origRequire);
  });
});
like image 186
es128 Avatar answered Sep 22 '22 14:09

es128