简体   繁体   English

如何使用 jasmine-ajax 来验证是否调用了 send 方法?

[英]How do I use jasmine-ajax to verify that the send method was called?

Should jasmine-ajax call onreadystatechange with a readyState of 4 if I never call the send method?如果我从不调用send方法, jasmine-ajax是否应该以 4 的readyState调用onreadystatechange

If the above is not the expected behavior, how do I use jasmine-ajax to verify that the send method was called?如果以上不是预期的行为,我如何使用jasmine-ajax来验证是否调用了send方法?

Here is the code under test:下面是测试中的代码:

    Loader = (function() {

      var loadNames = function(url, success_callback, error_callback) {

        var ajax = new XMLHttpRequest();

        ajax.open("GET", url);
        ajax.onreadystatechange = function () {
          console.log("Ready state is " + ajax.readyState);
          if (ajax.readyState === 4 && ajax.status === 200) {
            success_callback(JSON.parse(ajax.responseText));
          } else if (ajax.readyState === 4 && ajax.status !== 200) {
            error_callback("There was a problem. Status returned was " + ajax.status);
          }
        };

        ajax.onerror = function () {
         error_callback("Unknown error");
        };

        // Shouldn't removing the call to send prevent
        // onredystatechange from being called with readyState 4?
        // ajax.send();
      };

      return {
        loadNames: loadNames
      };

    })();

Here is the test:这是测试:

describe("Loader", function () {

  var successFunction, failFunction;

  beforeEach(function () {
    jasmine.Ajax.install();
    successFunction = jasmine.createSpy("successFunction");
    failFunction = jasmine.createSpy("failFunction");
  });

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

  describe("#loadNames", function () {    
    it("Makes a success callback with the data when successful", function () {
      Loader.loadNames("someURL", successFunction, failFunction);
      jasmine.Ajax.requests.mostRecent().respondWith({
        "status": 200,
        "contentType": 'application/json',
        "responseText": '[1, 2, 4, 3, 5]'
      });

      // Shouldn't this fail since I never called send?
      expect(successFunction).toHaveBeenCalledWith([1, 2, 4, 3, 5]);
    });
  });
});

I'm surprised to see that successFunction has been called because the code under test never calls ajax.send() .我很惊讶地看到successFunction已被调用,因为被测代码从不调用ajax.send() If this is the expected behavior of the library, then how do I spyOn the underlying ajax object so I can verify that the code under test calls send ?如果这是库的预期行为,那么我如何spyOn底层ajax对象,以便验证被测代码调用send

Yes you are not calling ajax.send() , but you are triggering the ajax.onreadystatechange event because of this piece of code:是的,您没有调用ajax.send() ,但是由于这段代码,您正在触发ajax.onreadystatechange事件:

jasmine.Ajax.requests.mostRecent().respondWith({
  "status": 200,
  "contentType": 'application/json',
  "responseText": '[1, 2, 4, 3, 5]'
});

Which changes the readystate and sets the readystate to done.它改变了就绪状态并将就绪状态设置为完成。 This is actually exactly as the documentation also states: https://jasmine.github.io/2.6/ajax.html这实际上与文档中所述的完全一样: https : //jasmine.github.io/2.6/ajax.html

As for how to check if xhr.send is actually being called, this SO answer explains you can spy on it doing the following in your beforeEach:至于如何检查 xhr.send 是否被实际调用,这个SO 答案解释说您可以在 beforeEach 中执行以下操作来监视它:

spyOn(XMLHttpRequest.prototype, 'send');

After uncommenting the xhr.send() part in your loader you could check for method calls like this:在您的加载程序中取消对 xhr.send() 部分的注释后,您可以检查如下方法调用:

describe("#loadNames", function () {    
  it("Makes a success callback with the data when successful", function () {
    Loader.loadNames("someURL", successFunction, failFunction);
    jasmine.Ajax.requests.mostRecent().respondWith({
      "status": 200,
      "contentType": 'application/json',
      "responseText": '[1, 2, 4, 3, 5]'
    });

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM