【问题标题】:How to spy jQuery AJAX request?如何监视 jQuery AJAX 请求?
【发布时间】:2012-08-23 08:50:52
【问题描述】:

下面两种实现ajaxRequest(1)(2)的方式应该是等价的。
话虽如此:

  1. 为什么验证回调的单元测试(3)执行,(1)成功,(2)失败?
  2. 我应该如何重写测试 (3) 以监视 (2) 中的成功回调?
  3. 如果我尝试使用 sinon 和代码 (2) stub jQuery.ajax,我会收到错误消息。我应该如何解决它?

请参阅代码 (3) 中的 cmets 了解更多详情。


(1)

ajaxRequest: function (message, callback) {
    return $.ajax({
        url: backendRouter.generate('feedback_send'),
        type: 'POST',
        dataType: 'json',
        data: {
            message: message
        },
        success: callback
    });
}

(2)

ajaxRequest: function (message, callback) {
    return $.ajax({
        url: backendRouter.generate('feedback_send'),
        type: 'POST',
        dataType: 'json',
        data: {
            message: message
        }
    }).success(callback);
}

(3)

it("should execute the callback function on success", function () {
    spyOn($, "ajax").andCallFake(function(options) {
        options.success();
    }); // If I use the code (2) I get the following error
        // TypeError: Object #<Object> has no method 'success'
    var callback = jasmine.createSpy();
    ajaxRequest('some message', callback);
    expect(callback).toHaveBeenCalled();
});

(4)

it("makes a GET request for todo items", function () {
    sinon.stub(jQuery, 'ajax');
    backendController.ajaxRequest('some message', sinon.spy()); 
    // Cannot call method 'success' of undefined
});

【问题讨论】:

    标签: javascript jquery jasmine


    【解决方案1】:

    这是一个演练:

    如果使用2号的代码,就是在jquery上调用ajax函数:

    return $.ajax({
      url: backendRouter.generate('feedback_send'),
      type: 'POST',
      dataType: 'json',
      data: {
        message: message
      }
    ...
    

    在使用这些参数调用此函数后,jQuery 返回一个 jqHR,它恰好定义了一个成功函数。然后调用该成功函数:

    ...
    }).success(callback);
    

    到目前为止,一切都很好,直到您的 jasmine 测试监视 ajax 函数。您用来调用 $.ajax 的相同选项将传递给这个新间谍。

    // this is the value of the options parameter
    {
        url: backendRouter.generate('feedback_send'),
        type: 'POST',
        dataType: 'json',
        data: {
            message: message
        }
    }
    

    当这个对象被传递时,你的假函数实际上试图调用options.success,它不存在!因此出现错误。

    【讨论】:

    • +1 感谢您的演练。实际上,现在我想编写一个测试(3)以便在代码(2)上运行它。你知道怎么做吗?我更新了我的问题。谢谢。
    • 显然,.success() 调用将在 jQuery 1.8 中被弃用。我建议不要使用 jasmine 来模拟您查看 sinon.js (sinonjs.org) 的 ajax 方法,它实际上会模拟您浏览器的本机 XHR。它对我很有用。
    • 我尝试stub jQuery.ajax,看到我的问题,代码(4)。我得到了错误,为什么?我应该得到sinonjs.org的哪个例子?
    • 是的,你可以使用 sinon 来存根 jquery 的函数,但这和 jasmine 的 spyOn 是一样的。 sinon 的特别有趣之处在于您可以伪造 XHR 和“伪造服务器”:sinonjs.org/docs/#server,请尝试使用这种方法。
    【解决方案2】:

    有一个 jquery 插件使用 sinonjs 和 qunit 并提供了一种更简单的方法来编写 ajax 测试并获得预期的结果。

    看看jqueryspy

    【讨论】:

      猜你喜欢
      • 2016-07-07
      • 2014-09-20
      • 1970-01-01
      • 2012-04-22
      • 2011-10-22
      • 2016-10-12
      • 1970-01-01
      相关资源
      最近更新 更多