Как использовать jasmine-ajax для проверки того, что метод отправки был вызван?

Должен ли jasmine-ajax вызывать onreadystatechange с readyState из 4, если я никогда не вызываю метод send?

Если приведенное выше поведение не является ожидаемым, как мне использовать 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.info("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?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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, этот ТАК ответ объясняет, что вы можете следить за ним, делая следующее в вашем 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 10.04.2019 22:26

@ Зак, да, это не очень хорошо объяснено, это как бы подразумевается этой частью: jasmine.Ajax.requests.mostRecent().respondWith({ "status": 200, "contentType": 'text/plain', "responseText": 'awesome response' }); expect(doneFn).toHaveBeenCalledWith('awesome response');. Похоже, это вызывает обратный вызов doneFn в документации, который эквивалентен вашему successFunction

etarhan 10.04.2019 22:29

Другие вопросы по теме