【问题标题】:How do I use jasmine-ajax to verify that the send method was called?如何使用 jasmine-ajax 来验证 send 方法是否被调用?
【发布时间】:2019-04-10 19:57:55
【问题描述】:

如果我从不调用send 方法,jasmine-ajax 是否应该使用readyState 4 来调用onreadystatechange

如果以上不是预期的行为,我如何使用jasmine-ajax 来验证send 方法是否被调用?

下面是测试代码:

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

    })();

这是测试:

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

我很惊讶地看到 successFunction 已被调用,因为被测代码从未调用 ajax.send()。如果这是库的预期行为,那么我如何spyOn 底层的ajax 对象,以便我可以验证被测代码是否调用send

【问题讨论】:

    标签: javascript ajax jasmine jasmine-ajax


    【解决方案1】:

    是的,您没有调用ajax.send(),但是由于这段代码,您正在触发ajax.onreadystatechange 事件:

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

    这会更改就绪状态并将就绪状态设置为完成。这实际上正如文档中所说的那样:https://jasmine.github.io/2.6/ajax.html

    至于如何检查 xhr.send 是否实际被调用,SO answer 解释说您可以在 beforeEach 中执行以下操作来监视它:

    spyOn(XMLHttpRequest.prototype, 'send');
    

    在您的加载器中取消注释 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();
      });
    });
    

    【讨论】:

    • 从那个页面我不清楚respondWith 会在没有send 被调用的情况下触发回调;但是,知道我正在观察预期的行为会很有帮助。对于它的价值,使用stubRequest 也会产生我需要的行为。
    • @Zack 是的,它没有很好地解释,这部分暗示了这一点:jasmine.Ajax.requests.mostRecent().respondWith({ "status": 200, "contentType": 'text/plain', "responseText": 'awesome response' }); expect(doneFn).toHaveBeenCalledWith('awesome response');。这似乎触发了文档中的doneFn 回调,相当于您的successFunction
    猜你喜欢
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    相关资源
    最近更新 更多