如何使用 Jasmine 验证 jQuery AJAX 事件? [英] How do I verify jQuery AJAX events with Jasmine?

查看:33
本文介绍了如何使用 Jasmine 验证 jQuery AJAX 事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

describe("jQuery ajax 请求应该能够获取...", function() {it("来自文件系统的 XML 文件", function() {$.ajax_get_xml_request = { has_returned : false };//发起 AJAX 请求$.ajax({ type: "GET", url: "addressbook_files/addressbookxml.xml", dataType: "xml",成功:函数(xml){警报(yuppi!");$.ajax_get_xml_request.has_returned = true;} });//等待 has_returned 变为真(超时:3s)waitsFor(function() { $.ajax_get_xml_request.has_returned; }, "JQuery AJAX GET 返回", 3000);//TODO: 其他测试可能会检查 XML 文件的大小,是否是有效的 XML期望($.ajax_get_xml_request.has_returned).toEqual(true);});});

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

解决方案

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

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

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

以下是如何伪造 AJAX 请求的示例,然后编写单元测试以验证伪造的 AJAX 请求是否发送到正确的 URL:

it("应该向正确的 URL 发出 AJAX 请求", function() {间谍($,阿贾克斯");获取产品(123);期望($.ajax.mostRecentCall.args[0]["url"]).toEqual("/products/123");});函数 getProduct(id) {$.ajax({类型:获取",url: "/products/" + id,contentType: "application/json; charset=utf-8",数据类型:json"});}

对于 Jasmine 2.0 使用:

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

中所述这个答案

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

it("应该在成功时执行回调函数", function () {spyOn($, "ajax").andCallFake(function(options) {options.success();});var 回调 = jasmine.createSpy();getProduct(123, 回调);期望(回调).toHaveBeenCalled();});函数 getProduct(id, callback) {$.ajax({类型:获取",url: "/products/" + id,contentType: "application/json; charset=utf-8",数据类型:json",成功:回调});}

对于 Jasmine 2.0 使用:

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

此答案中所述

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

it("应该发出一个真正的 AJAX 请求", function () {var 回调 = jasmine.createSpy();getProduct(123, 回调);等待(功能(){返回 callback.callCount >0;});运行(功能(){期望(回调).toHaveBeenCalled();});});函数 getProduct(id, callback) {$.ajax({类型:获取",网址:data.json",内容类型:应用程序/json;字符集=utf-8"数据类型:json",成功:回调});}

I am trying to use Jasmine to write some BDD specs for basic jQuery AJAX requests. I am currently using Jasmine in standalone mode (i.e. through SpecRunner.html). I have configured SpecRunner to load jquery and other .js files. Any ideas why the following doesn't work? has_returned does not become true, even thought the "yuppi!" alert shows up fine.

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

});

How do I test that the callback has been called? Any pointers to blogs/material related to testing async jQuery with Jasmine will be greatly appreciated.

解决方案

I guess there are two types of tests you can do:

  1. Unit tests that fake the AJAX request (using Jasmine's spies), enabling you to test all of your code that runs just before the AJAX request, and just afterwards. You can even use Jasmine to fake a response from the server. These tests would be faster - and they would not need to handle asynchronous behaviour - since there isn't any real AJAX going on.
  2. Integration tests that perform real AJAX requests. These would need to be asynchronous.

Jasmine can help you do both kinds of tests.

Here is a sample of how you can fake the AJAX request, and then write a unit test to verify that the faked AJAX request was going to the correct 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"
    });
}

For Jasmine 2.0 use instead:

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

as noted in this answer

Here is a similar unit test that verifies your callback was executed, upon an AJAX request completing successfully:

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

For Jasmine 2.0 use instead:

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

as noted in this answer

Finally, you have hinted elsewhere that you might want to write integration tests that make real AJAX requests - for integration purposes. This can be done using Jasmine's asyncronous features: waits(), waitsFor() and 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
    });
}

这篇关于如何使用 Jasmine 验证 jQuery AJAX 事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆