如何使用Jasmine和/或Sinon正确单元测试jQuery的.ajax()承诺?



我有一个相当简单的函数,它返回jQuery .ajax()有望这样:

CLAW.controls.validateLocation = function(val, $inputEl) {
    return $.ajax({
        url: locationServiceUrl + 'ValidateLocation/',
        data: {
            'locationName': val
        },
        beforeSend: function() {
            $inputEl.addClass('busy');
        }
    }).done(function(result) {
        // some success clauses
    }).fail(function(result) {
        // some failure clauses
    }).always(function() {
        // some always clauses
    });
}

在大多数情况下,这种新的承诺界面就像梦一样工作,并且在使用jQuery的.ajax()时消除了回调金字塔很棒。但是,我一生无法弄清楚如何使用茉莉花和/或辛农来正确测试这些诺言:

  1. Sinon的所有文档都假定您正在使用老式的文档回调;我看不到如何使用它的一个示例承诺/延期

  2. 尝试使用茉莉花或辛农间谍来监视$ .ajax,间谍正在有效地覆盖承诺,因此其donefailalways条款不再存在于Ajax函数上,因此承诺永远不会解决和抛弃错误

我真的很喜欢一个或两个如何测试这些新的jQuery .ajax()承诺的示例,并通过上述测试液体承诺。我已经相当强烈地搜寻了"网络",但并没有真正挖出任何事情。我确实发现了使用Jasmine.ajax提到的一种资源,但是如果可能的话,我想避免使用,因为Sinon提供了大部分相同的功能。

实际上不是那么复杂。归还诺言并根据您的案件解决它足够。

例如:

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

成功,

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

失败。

对于茉莉花2.0,语法略有变化:

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

方法.andcallfake()在茉莉2.0

中不存在

沿这些线/带有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());

这是一种简单的方法。

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();
            }

我在测试中使用的每个回调的语句是驱动成功或错误执行的方法。

如果您使用.complete()之类的东西,@GGOZAD给出的解决方案将无法正常工作。

但是,hooray,茉莉花制作了一个插件来做到这一点: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');

最新更新