Mocking an anonymous module call in Jasmine using requireJs

609 Views Asked by At

Current unit testing setup:

  • Jasmine 2.1
  • RequireJs 2.1.15
  • Chutzpah 3.2.6

In our code base we have a number of modules which are loaded in through requireJs to abstract out functionality. For example communications which abstracts away calls to the server. However these modules return an anonymous function:

define(['jquery'], function ($) {

    return function (method, link, payload) {
        // code removed as not required for question
        return $.ajax({
            type: method,
            url: link,
            data: payload
        });
    };
})

This is then imported through requireJs/AMD loading by other modules and used in the following way:

var promise = communicator("GET", "/url/to/my/webapi", {});

I currently have a mock module which gets imported for the unit tests bypassing the $.ajax call and returns a promise however I really want to test in my unit tests that it has been called or not and the correct values have been passed in etc. I have tried looking at spies however as it doesn't expose a named function on the module I am unable to use this method as far as I can tell.

How can I go about setting up expectations/mocking an anonymous AMD returned function?

EDIT

Example of usage to aid with clarity:

define(['communicator'], function (communicator) {

        var vm = function (id) {
            var self = this;

            self.Id = id

            self.submitForm = function () {
                var data = { };

                var promise = communicator("PUT", "/url/to/web/api", data);

                promise.done(function (message) {
                });

                promise.fail(function (error) {
                });
            };
        };

        return {
            initialise: function (params) {
                var viewModel = new vm(params.Id);
                return viewModel;
            }
        };
    });

I want to be able to test the submitForm function (simplified for question purposes) and want to mock the communicator dependency without defining a stubbed additional module in the testing project require.js setup.

2

There are 2 best solutions below

1
On BEST ANSWER

I'm not sure exactly what you need to test, but you could spyOn $.ajax and create your own promise...

window.spyOn($, "ajax").and.callFake(function() {
  var d = $.Deferred();
  d.resolve(true);
  return d.promise();
});

expect($.ajax).toHaveBeenCalled();
// other expects...
0
On

In the end I went with changing the module to have specific methods on which could then be spied on. I have other modules which are of the same pattern though so will continue on my quest.