javascript - 如何使用 Jasmine 验证 jQuery AJAX 事件?

标签 javascript jquery ajax jasmine bdd

我正在尝试使用 Jasmine 为基本的 jQuery AJAX 请求编写一些 BDD 规范。我目前在独立模式下使用 Jasmine(即通过 SpecRunner.html)。我已将 SpecRunner 配置为加载 jquery 和其他 .js 文件。为什么以下不起作用的任何想法? has_returned 不会变为真,甚至认为“雅皮士!”警报显示正常。

describe("A jQuery ajax request should be able to fetch...", function() {

  it("an XML file from the filesystem", function() {
    $.ajax_get_xml_request = { has_returned : false };  
    // initiating the AJAX request
    $.ajax({ type: "GET", url: "addressbook_files/addressbookxml.xml", dataType: "xml",
             success: function(xml) { alert("yuppi!"); $.ajax_get_xml_request.has_returned = true; } }); 
    // waiting for has_returned to become true (timeout: 3s)
    waitsFor(function() { $.ajax_get_xml_request.has_returned; }, "the JQuery AJAX GET to return", 3000);
    // TODO: other tests might check size of XML file, whether it is valid XML
    expect($.ajax_get_xml_request.has_returned).toEqual(true);
  }); 

});

如何测试回调是否已被调用?非常感谢任何指向与使用 Jasmine 测试异步 jQuery 相关的博客/ Material 的指针。

最佳答案

我猜你可以做两种类型的测试:

  1. 伪造 AJAX 请求的单元测试(使用 Jasmine 的 spy ),使您能够测试在 AJAX 请求之前之后运行的所有代码。您甚至可以使用 Jasmine 伪造来自服务器的响应。这些测试会更快 - 而且它们不需要处理异步行为 - 因为没有任何真正的 AJAX 正在进行。
  2. 执行真实 AJAX 请求的集成测试。这些需要是异步的。

Jasmine 可以帮助您进行这两种测试。

下面是一个示例,说明如何伪造 AJAX 请求,然后编写单元测试来验证伪造的 AJAX 请求是否转到正确的 URL:

it("should make an AJAX request to the correct URL", function() {
    spyOn($, "ajax");
    getProduct(123);
    expect($.ajax.mostRecentCall.args[0]["url"]).toEqual("/products/123");
});

function getProduct(id) {
    $.ajax({
        type: "GET",
        url: "/products/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    });
}

对于 Jasmine 2.0,请改用:

expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/products/123");

this answer 中所述

这是一个类似的单元测试,用于在 AJAX 请求成功完成后验证您的回调是否已执行:

it("should execute the callback function on success", function () {
    spyOn($, "ajax").andCallFake(function(options) {
        options.success();
    });
    var callback = jasmine.createSpy();
    getProduct(123, callback);
    expect(callback).toHaveBeenCalled();
});

function getProduct(id, callback) {
    $.ajax({
        type: "GET",
        url: "/products/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: callback
    });
}

对于 Jasmine 2.0,请改用:

spyOn($, "ajax").and.callFake(function(options) {

this answer 中所述

最后,您在别处暗示您可能想要编写发出真正 AJAX 请求的集成测试 - 用于集成目的。这可以使用 Jasmine 的异步功能来完成:waits()、waitsFor() 和 runs():

it("should make a real AJAX request", function () {
    var callback = jasmine.createSpy();
    getProduct(123, callback);
    waitsFor(function() {
        return callback.callCount > 0;
    });
    runs(function() {
        expect(callback).toHaveBeenCalled();
    });
});

function getProduct(id, callback) {
    $.ajax({
        type: "GET",
        url: "data.json",
        contentType: "application/json; charset=utf-8"
        dataType: "json",
        success: callback
    });
}

关于javascript - 如何使用 Jasmine 验证 jQuery AJAX 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4662641/

相关文章:

javascript - 如何让页面内容始终出现在导航栏下方?

javascript - 卡住 HTML 表格标题

javascript - 如何使用 JS/jQuery 获取元素的高度?

javascript - 如何实现代码按钮来格式化文本区域中的文本?

php - 使用 php ajax 在将数据从数据库检索到搜索框时显示结果

javascript - 使用 interactive-background.js

javascript - 滑动 Material 设计卡片 View

javascript - JS 或 Jquery 创建唯一的 span ID

javascript - 跟踪滚动事件的页码

javascript - 在 Django 中实时编辑