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

2022-08-30 05:23:47

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

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

});

如何测试是否已调用回调?任何指向与使用茉莉花测试异步jQuery相关的博客/材料的指针将不胜感激。


答案 1

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

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

茉莉花可以帮助你做这两种测试。

下面是如何伪造 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"
    });
}

对于茉莉花2.0,请改用:

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

本答案中所述

下面是一个类似的单元测试,用于验证在 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
    });
}

对于茉莉花2.0,请改用:

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

本答案中所述

最后,您在其他位置暗示,您可能希望编写生成真正的 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
    });
}

答案 2

看看茉莉花-阿贾克斯项目:http://github.com/pivotal/jasmine-ajax

这是一个插入式帮助程序(对于jQuery或Prototype.js)XHR层的存根,以便请求永远不会发出。然后,您可以期待有关请求的所有期望。

然后,它允许您为所有情况提供夹具响应,然后为所需的每个响应编写测试:成功,失败,未经授权等。

它使Ajax调用脱离了异步测试的领域,并为您提供了很大的灵活性来测试实际响应处理程序的工作方式。