使用 Jasmine 模拟 jQuery ajax 调用

2024-05-10

我正在使用 Jasmine 2.5.2 为使用 jQuery 3.1.1 执行 Ajax 请求的代码编写单元测试。我想模拟 Ajax 调用,提供我自己的响应状态和文本。

我正在使用 Jasmine ajax 插件(https://github.com/pivotal/jasmine-ajax https://github.com/pivotal/jasmine-ajax).

下面的例子https://jasmine.github.io/2.0/ajax.html https://jasmine.github.io/2.0/ajax.html,它使用 XMLHttpRequest 对象,工作正常。

describe("mocking ajax", function() {
    describe("suite wide usage", function() {
        beforeEach(function() {
            jasmine.Ajax.install();
        });

        afterEach(function() {
            jasmine.Ajax.uninstall();
        });

        it("specifying response when you need it", function() {
            var doneFn = jasmine.createSpy("success");

            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(args) {
                if (this.readyState == this.DONE) {
                    doneFn(this.responseText);
                }
            };

            xhr.open("GET", "/some/cool/url");
            xhr.send();
            expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
            expect(doneFn).not.toHaveBeenCalled();

            jasmine.Ajax.requests.mostRecent().respondWith({
                "status": 200,
                "contentType": 'text/plain',
                "responseText": 'awesome response'
            });
            expect(doneFn).toHaveBeenCalledWith('awesome response');                      
        });
    });
});

注意:这与记录的示例略有不同,必须更改jasmine.Ajax.requests.mostRecent().response() to jasmine.Ajax.requests.mostRecent().respondWith().

当我使用 jQuery Ajax 时,doneFn 永远不会被调用。

describe("mocking ajax", function() {
    describe("suite wide usage", function() {
        beforeEach(function() {
            jasmine.Ajax.install();
        });

        afterEach(function() {
            jasmine.Ajax.uninstall();
        });

        it("specifying response when you need it", function() {
            var doneFn = jasmine.createSpy("success");

            $.ajax({
                method: "GET",            
                url: "/some/cool/url"})
            .done(function(result) {
                doneFn(result);
            });
            expect(doneFn).toHaveBeenCalledWith('awesome response');                      
        });
    });
});

茉莉花指出

Jasmine-Ajax 模拟了您的请求 XMLHttpRequest 对象,因此应该与其他对象兼容 执行 ajax 请求的库。

$.ajax 从 1.4.x 返回 jqXHR 而不是 XMLHttpRequest - 这是否会破坏 Jasmine Ajax 的支持?


以下是您可以在 jasmine 测试中模拟 ajax 的几种方法

方法一:

  • 使用模拟 ajax.js,您可以模拟全局 xhr 对象,如doc https://jasmine.github.io/2.5/ajax.html
  • 但是,您需要在 success 函数上指定一个间谍并让它 callThrough (如下面的代码所示)
  • 查看实际效果here https://jsfiddle.net/randomfifaguy/w1usxb7x/24/

    describe('ajax test suite', function() {
    
      beforeEach(function() {
        jasmine.Ajax.install();
      });
    
      afterEach(function() {
        jasmine.Ajax.uninstall();
      });
    
      it('sample test', function() {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(args) {
          if (this.readyState == this.DONE) {
            testObj.successFunction(this.responseText);
          }
        };
        spyOn(testObj, 'successFunction').and.callThrough();
        xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1");
        xhr.send();
        expect(jasmine.Ajax.requests.mostRecent().url).toBe('https://jsonplaceholder.typicode.com/posts/1');
        expect(testObj.successFunction).not.toHaveBeenCalled();
        jasmine.Ajax.requests.mostRecent().respondWith({
          "status": 200,
          "contentType": 'text/plain',
          "responseText": 'awesome response'
        });
        expect(testObj.successFunction).toHaveBeenCalledWith('awesome response');
      });
    });
    

方法B:

  • 直接模拟 $.ajax 对象。无论是 get/post/load 还是来自 jquery 的任何 ajax 风格,您都可以简单地模拟 $.ajax,如下所示。

    var testObj = {
      ajaxFunction : function(url){     
       $.ajax({url : url}).done(this.successFunction.bind(this));
      },
      successFunction : function(data){
       console.log(data);
     }
    }
    
    describe('ajax test suite', function(){
        it('sample test', function(){
         testObj.ajaxFunction('https://jsonplaceholder.typicode.com/posts/1');
         spyOn($, 'ajax').and.callFake(function(e) {
              return $.Deferred().resolve({'text':'this a a fake response'}).promise();
         });
         spyOn(testObj, 'successFunction').and.callThrough();
         testObj.ajaxFunction('https://jsonplaceholder.typicode.com/posts/1');
         expect(testObj.successFunction).toHaveBeenCalledWith({'text':'this a a fake response'});
      });
    });
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Jasmine 模拟 jQuery ajax 调用 的相关文章

随机推荐

  • android:widgetLayout 和 android:layout 之间的区别?

    我得到一些奇怪的配置 其中 widgetLayout 配置列表项的内部空间 而布局配置整个项目列表和屏幕背景 有人能真正解释一下什么是 widgetLayout 吗 android layout 整个首选项的布局 包括标题 摘要和小部件 a
  • 如何创建到任何 fancybox 框的直接链接

    我需要当我单击任何使用 fancybox 的内容时 它会生成一个特定的 URL 因此当我将此链接发送给某人时 它会打开我想要的特定框 例如 fancybox net home当我点击第一张图片时 链接仍然存在fancybox net hom
  • Laravel 中如何返回数组而不是集合?

    在 Laravel 中 可以仅选择一个字段并将其作为集合 数组返回 例如考虑模型Foo链接到表foos其中有字段id a b c 考虑以下示例数据 1 10 15 20 1 12 15 27 1 17 15 27 1 25 16 29 1
  • X11剪贴板如何处理多种数据格式?

    这可能也发生在您身上 有时 当您将某个网页中的文本复制到您最喜欢的网络邮件客户端中的富文本电子邮件草稿中时 您不喜欢粘贴的内容piece有不同的字体 大小 粗细 它以某种方式记住样式 通常是图像 当选择时 如果您将相同的内容粘贴到您最喜欢的
  • 获取MySql中重复行的列表

    我有一张这样的桌子 ID nachname vorname 1 john doe 2 john doe 3 jim doe 4 Michael Knight 我需要一个查询 该查询将从具有相同 nachname 和 vorname 的记录
  • 什么是标准 unicode 字体?

    以下操作系统的标准 unicode 字体是什么 视窗XP 视窗Vista Window 7 按照标准 我的意思是它们存在于操作系统的全新安装中 无需将它们作为附加包安装 我一直在寻找同样的东西 看起来所有 Win 操作系统中只有一种字体 L
  • WebView2 在没有 WebView2 运行时的情况下工作

    我们尝试在没有 WebView2 运行时的情况下使用 WebView2 因为它的大小为 100 MB 并将其分发给客户端 它在 2 台 PC 上进行了测试 两者都有相同版本的 Edge 在 PC1 上 如果没有 WV2 运行时 WebVie
  • 低级挂钩/SetWindowsHookEx lParam 自动重复?

    在这里阅读 Windows PC 上如何实现键盘自动重复 https stackoverflow com questions 876852 how is keyboard auto repeat implemented on a windo
  • 在 EmberJS 中获取父路由

    我正在制作一个可重用 有点多态 的评论小部件 我想要一个按钮 使我能够返回到父路由 例如 如果我位于 blog posts 1 comments 我希望该按钮将我带回 blog posts 1 我目前正在使用transitionToRout
  • 如何使用 JQuery 隐藏和显示 HTML 元素?

    如何使用 JQuery 隐藏和显示 HTML 元素而不产生任何特殊效果 使用hide http docs jquery com Effects hide and show http docs jquery com Effects show方
  • 如何自定义JProgressBar?

    我正在制作一个启动器 我想要一个自定义的进度栏 我已经做了一些研究 并且可以使用 JavaFX 从未用它做过任何事情 并且可以通过替换 UI 来实现 我正在寻找一个具有圆形边缘和圆形填充的酒吧 像这样的事情 package gui impo
  • EXC_BAD_INSTRUCTION 的 CoreData 错误(代码=EXC_I386_INVOP,子代码=0x0)

    当我打开并发调试开关 com apple CoreData ConcurrencyDebug 1 来跟踪 CoreData 的所有并发问题时 在调用 insertingNewObjectForEntityForName 时不断发生崩溃 Xc
  • Google Apps 脚本:在电子邮件中发送 PDF 而不是 .zip 文件

    我有这段代码 可以从 Google 电子表格生成 PDF 文件并将其作为电子邮件附件发送 问题是它压缩文件const zipBlob Utilities zip blobs setName ss getName zip 我想更改它 以便附加
  • 在 JavaScript 中引用 C# 变量

    我已经阅读了很多线程 但我不明白为什么这不起作用 我正在创建一个将用作导航栏的 SharePoint Web 部件 一切都很顺利 直到我尝试在 JS 代码中引用 C 变量 这是来自 VisualWebPart1UserControl asc
  • 使用 PHP 比较两个字符串的相似度

    嘿伙计们 我想寻求一些解决方案 现在我有字典了单词 txt 这里有一些例子 happy laugh sad 我有俚语字符串 hppy 我想要搜索和匹配那个俚语字符串我的字典这意味着它将返回 happy 因为这些字符串参考 快乐 in 字典
  • 如何解决创建 SwiftData #Predicate 的编译器错误?

    我一直在尝试很多方法来解决这个问题 我正在尝试使用谓词获取 SwiftData 记录 但我尝试的一切都会导致两个错误 初始化程序 init 要求 Item 符合 Encodable 初始化程序 init 要求 Item 符合 Decodab
  • 从源安全导出

    有没有办法从 Source Safe 导出文件 文件夹 即删除所有 scc 文件 就像 SVN 导出一样 只需进行常规获取 然后运行类似的操作 ATTRIB R scc S DEL F S Q scc 第一个命令从这些文件中删除只读标志 第
  • 使用 Python 抓取维基百科数据

    我正在尝试从以下内容中检索 3 列 NFL 球队 球员姓名 大学球队 维基百科页面 http en wikipedia org wiki 2008 NFL draft 我是 python 新手 一直在尝试使用 beautifulsoup 来
  • pandas 两个数据框交叉连接[重复]

    这个问题在这里已经有答案了 我找不到有关交叉联接的任何内容 包括合并 联接或其他一些内容 我需要使用 my function 作为 myfunc 处理两个数据帧 相当于 for itemA in df1 iterrows for itemB
  • 使用 Jasmine 模拟 jQuery ajax 调用

    我正在使用 Jasmine 2 5 2 为使用 jQuery 3 1 1 执行 Ajax 请求的代码编写单元测试 我想模拟 Ajax 调用 提供我自己的响应状态和文本 我正在使用 Jasmine ajax 插件 https github c