使用Jasmine模拟jQuery ajax调用 [英] Mocking jQuery ajax calls with Jasmine

查看:209
本文介绍了使用Jasmine模拟jQuery ajax调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Jasmine 2.5.2 to write unit tests for code that performs Ajax requests using jQuery 3.1.1 . I would like to mock out the Ajax call, providing my own response status and text.

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

I am using the Jasmine ajax plug-in (https://github.com/pivotal/jasmine-ajax).

按照 https://jasmine.github.io/2.0/ajax.html上的示例进行操作,使用XMLHttpRequest对象,工作正常。

Following the example on https://jasmine.github.io/2.0/ajax.html, which uses the XMLHttpRequest object, works fine.

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() jasmine.Ajax.requests.mostRecent()。respondWith()

NB: this differs slightly from the documented example, had to change jasmine.Ajax.requests.mostRecent().response() to jasmine.Ajax.requests.mostRecent().respondWith().

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

When I use jQuery Ajax, the doneFn is never called.

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表示


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

Jasmine-Ajax mocks out your request at the XMLHttpRequest object, so should be compatible with other libraries that do ajax requests.

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

$.ajax returns a jqXHR from 1.4.x and not XMLHttpRequest - does this break support with Jasmine Ajax?

推荐答案

以下几种方法可以在茉莉花测试中模拟ajax

Here are a couple of ways you could mock ajax in your jasmine tests

方法A:


  • 使用mock ajax.js,您可以按照 doc

  • 但是你需要在成功函数上指定一个间谍并让它调用(通过以下代码)

  • 查看实际操作此处

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,如下所示。

  • Directly mocking the $.ajax object. Be it get/post/load or any ajax flavor from jquery, you can simply mock the $.ajax as shown below.

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


这篇关于使用Jasmine模拟jQuery ajax调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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