Mock RequireJS define dependencies with config.map

I had a module dependency, that I’m pulling down with RequireJS that I needed to use and write tests against. In this case, I don’t care about the actual implementation of the module (it’s simple enough that I’m just avoiding some AJAX calls).

EDIT: make sure you look at the bottom example after the edit before using the config.map approach. I found that there is an easier way.

I did not want to change the constructor of the consumer as I had a chain of changes that would have to be made and that would have been to invasive for this task.

I found a question on StackOverflow with a short, but helpful answer from “Artem Oboturov”. We can use the config.map from RequireJs to achieve this.

Here is some code:

A module example (“usefulModule” in Common/Modules/usefulModule.js):

define([], function() { "use strict"; var testMethod = function() { ... }; // add more functionality of the module return { testMethod; } });

A consumer of usefulModule example:

define([ "Commmon/Modules/usefulModule" ], function(usefulModule) { "use strict"; var consumerModule = function(){ var self = this; // add functionality of the module } });

Using config.map in the html of the test runner page (and in your Karma config –> I’m still trying to figure this out):

map: {'*': { // replace usefulModule with a mock 'Common/Modules/usefulModule': '/Tests/Specs/Common/usefulModuleMock.js' } }

With the new mapping, Require will load usefulModuleMock.js from Tests/Specs/Common instead of the real implementation.

Some of the answers on StackOverflow mentioned Squire.js, which looked interesting, but I wasn’t ready to introduce a new library at this time.

That’s all you need to be able to mock a depency in RequireJS. However, there are many good cases when you should pass it in through the constructor instead of this approach.

EDIT: After all that, here’s another, probably better way:

The consumer class, updated:

define([ "Commmon/Modules/usefulModule" ], function(UsefulModule) { "use strict"; var consumerModule = function(){ var self = this; self.usefulModule = new UsefulModule(); // add functionality of the module } });

Jasmine test:

define([ "consumerModule", "/UnitTests/Specs/Common/Mocks/usefulModuleMock.js" ], function(consumerModule, UsefulModuleMock){

describe("when mocking out the module", function(){
    it("should probably just override the property", function(){
      var consumer = new consumerModule();
      consumer.usefulModule = new UsefulModuleMock();
    });
});

});

Thanks for letting me think out loud :-).