How to properly unit test jQuery's .ajax() promises using Jasmine and/or Sinon?

ε祈祈猫儿з 提交于 2019-11-28 03:03:48

It is not that complex actually. It suffices to return a promise and resolve it according to your case.

For example:

spyOn($, 'ajax').andCallFake(function (req) {
    var d = $.Deferred();
    d.resolve(data_you_expect);
    return d.promise();
});

for a success, or

spyOn($, 'ajax').andCallFake(function (req) {
    var d = $.Deferred();
    d.reject(fail_result);
    return d.promise();
});

for a failure.

For Jasmine 2.0 the syntax has changed slightly:

spyOn($, 'ajax').and.callFake(function (req) {});

the method .andCallFake() does not exist in Jasmine 2.0

something along these lines / with sinon and jQuery deferreds

ajaxStub = sinon.stub($, "ajax");

function okResponse() {
  var d = $.Deferred();
  d.resolve( { username: "testuser", userid: "userid", success: true } );
  return d.promise();
};

function errorResponse() {
 var d = $.Deferred();
 d.reject({},{},"could not complete");
 return d.promise();
};

ajaxStub.returns(okResponse());
ajaxStub.returns(errorResponse());

Here's a simpler approach with just javascript.

quoteSnapshots: function (symbol, streamId) {
                var FakeDeferred = function () {
                    this.error = function (fn) {
                        if (symbol.toLowerCase() === 'bad-symbol') {
                            fn({Error: 'test'});
                        }
                        return this;
                    };
                    this.data = function (fn) {
                        if (symbol.toLowerCase() !== 'bad-symbol') {
                            fn({});
                        }
                        return this;
                    };
                };

                return new FakeDeferred();
            }

The if statements inside of each callback are what I use in my test to drive a success or error execution.

The solution given by @ggozad won't work if you use things like .complete().

But, hooray, jasmine made a plugin to do exactly this: http://jasmine.github.io/2.0/ajax.html

beforeEach(function() {
  jasmine.Ajax.install();
});

afterEach(function() {
  jasmine.Ajax.uninstall();
});

//in your tests
expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!