javascript 如何使用 Jasmine 测试 XMLHttpRequest

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8901445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 04:55:20  来源:igfitidea点击:

How to test XMLHttpRequest with Jasmine

javascriptajaxjasmine

提问by toy

How can I test the onreadystatechange on XMLHttpRequest or pure Javascript AJAX without jQuery? I'm doing this because I'm developing Firefox extension. I guess I have to use spies, but couldn't figure out how because my ajax won't return anything.

如何在没有 jQuery 的情况下测试 XMLHttpRequest 或纯 Javascript AJAX 上的 onreadystatechange?我这样做是因为我正在开发 Firefox 扩展。我想我必须使用间谍,但不知道怎么做,因为我的 ajax 不会返回任何东西。


    submit : function() {
        var url = window.arguments[0];
        var request = new XMLHttpRequest();
        request.open("POST", 'http://'+this.host+'/doSomething', true);
        request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        request.send("param="+param+"&emotions="+this.getParams());
        request.onreadystatechange = function() {
            if(this.readyState == 4) {
                // alert(this.responseText);
            }
        };

    }

采纳答案by Andreas K?berle

As mention in the comments with SinonJSyou can easily mock the XHR object / create a fake server.

正如在使用SinonJS的评论中提到的,您可以轻松模拟 XHR 对象/创建假服务器

回答by mcepl

And what about this one?

而这个呢?

beforeEach(function() {
  // spyOn(XMLHttpRequest.prototype, 'open').andCallThrough(); // Jasmine 1.x
  spyOn(XMLHttpRequest.prototype, 'open').and.callThrough(); // Jasmine 2.x
  spyOn(XMLHttpRequest.prototype, 'send');
});

...

it("should call proper YQL! API", function() {
  podcast.load_feed('http://www.faif.us/feeds/cast-ogg/');

  expect(XMLHttpRequest.prototype.open).toHaveBeenCalled();
});

Pure Jasmine without need to use any external library.

纯 Jasmine,无需使用任何外部库。

回答by Alvis

You can test it in such manner

你可以用这种方式测试它

it("should make XHR request", function() {

   // arrange

    var xhr = {
        open: jasmine.createSpy('open')
    };

    XMLHttpRequest = jasmine.createSpy('XMLHttpRequest');
    XMLHttpRequest.and.callFake(function () {
        return xhr;
    });

    // act

    submit();

    // assert

    expect(xhr.open).toHaveBeenCalled(); 
});

回答by serv-inc

Provided by jasmine-ajax. To mock for a single spec use withMock:

jasmine-ajax 提供。模拟单个规范使用withMock

  it("allows use in a single spec", function() {
    var doneFn = jasmine.createSpy('success');
    jasmine.Ajax.withMock(function() {
      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(doneFn).not.toHaveBeenCalled();

      jasmine.Ajax.requests.mostRecent().respondWith({
        "status": 200,
        "responseText": 'in spec response'
      });

      expect(doneFn).toHaveBeenCalledWith('in spec response');
    });
  });
  it("allows use in a single spec", function() {
    var doneFn = jasmine.createSpy('success');
    jasmine.Ajax.withMock(function() {
      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(doneFn).not.toHaveBeenCalled();

      jasmine.Ajax.requests.mostRecent().respondWith({
        "status": 200,
        "responseText": 'in spec response'
      });

      expect(doneFn).toHaveBeenCalledWith('in spec response');
    });
  });

The response is only sent when you use respondWith. Just download the file, and add as a srcto your SpecRunner.html. Example usage at https://github.com/serv-inc/JSGuardian(see the test folder).

响应仅在您使用时发送respondWith。只需下载该文件,并将其添加src到您的SpecRunner.html. https://github.com/serv-inc/JSGuardian 中的示例用法(请参阅测试文件夹)。

回答by CBusBus

As per the facsimile of your code below you will likely be able to inject console.log() with the status code and status text.

根据下面的代码传真,您可能可以将状态代码和状态文本注入 console.log() 。

This will help you identify any http errors. Speculatively I'd say the status will return 404.

这将帮助您识别任何 http 错误。推测我会说状态将返回 404。

submit : function() {
    var url = window.arguments[0];
    var request = new XMLHttpRequest();
    request.open("POST", 'http://'+this.host+'/doSomething', true);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.send("param="+param+"&emotions="+this.getParams());
    request.onreadystatechange = function() {
        console.log(this.status+ " - "+ this.statusText);
    };

}

An alternative to this would be to look at the request header / response within the firebug console. Which is a good point: If you're not using firebug or chrome dev tools you should change the console.log() call to something that appends the string to a document object do notuse an alert() call.

另一种方法是查看萤火虫控制台中的请求标头/响应。这是一个很好的观点:如果您不使用 firebug 或 chrome 开发工具,您应该将 console.log() 调用更改为将字符串附加到文档对象的内容,不要使用 alert() 调用。

How do I verify jQuery AJAX events with Jasmine?. A similar answer that implements Jasmine.

如何使用 Jasmine 验证 jQuery AJAX 事件?. 实现 Jasmine 的类似答案。