Подтвердить что ты не робот

Как подделать ответ jquery.ajax()?

Я пишу несколько тестов QUnit для JavaScript, который вызывает вызовы AJAX.

Для изоляции я перезаписываю $.ajax, чтобы написать массив параметров вызова AJAX для переменной. Это работает, чтобы проверить, как методы используют функции AJAX, но мне трудно проверить обработчик успеха $.load()

Из документации в http://api.jquery.com/load/:

Когда обнаружен успешный ответ (т.е. когда textStatus является "успешным" или "немодифицированным" ),.load() устанавливает содержимое HTML сопоставленного элемента в возвращаемые данные.

Итак, я попытался вернуть объект, содержащий объекты с тем же именем, что и переменные для обработчика успеха:

    //Mock ajax function
    $.ajax = function (param) {
        _mockAjaxOptions = param;
        var fakeAjaxSuccess = { responseText: "success", textStatus: "success", XMLHttpRequest: "success" };
        return fakeAjaxSuccess;
    };

Но этот подход не сработал.

Как я могу воспроизвести поведение успешного вызова AJAX?

4b9b3361

Ответ 1

После чтения, вдохновленного @Robusto и @Val, я нашел метод, который работает:

//Mock ajax function
$.ajax = function (param) {
    _mockAjaxOptions = param;
    //call success handler
    param.complete("data", "textStatus", "jqXHR");
};

Вместо того, чтобы поднимать событие из любого реального кода $.ajax или запускать любые события, у меня есть мой поддельный объект ajax, вызывающий функцию (которая передается как параметр в $.ajax()) как часть моей поддельной функции.

Ответ 2

У этого вопроса есть несколько лет, и для новых версий jQuery немного изменилось.

Чтобы сделать это с помощью Jasmin, вы можете попробовать подход Майкла Фалаги

Решение

  function ajax_response(response) {
    var deferred = $.Deferred().resolve(response);
    return deferred.promise();
  }

С жасмином

  describe("Test test", function() {
    beforeEach(function() {
      spyOn($, 'ajax').and.returnValue(
        ajax_response([1, 2, 3])
      );
    });
    it("is it [1, 2, 3]", function() {
      var response;
      $.ajax('GET', 'some/url/i/fancy').done(function(data) {
        response = data;
      });
      expect(response).toEqual([1, 2, 3]);
    });
  });

Нет жасмина

  $.ajax = ajax_response([1, 2, 3]);
  $.ajax('GET', 'some/url/i/fancy').done(function(data) {
     console.log(data); // [1, 2, 3]
  });

Ответ 3

Используйте замыкание для переопределения $.ajax с фиктивным ответом

После попытки принятого ответа и ответа, опубликованного пользователем1634074, я разработал эту простую и гибкую смесь из двух.

В своей самой простой форме...

function ajax_response(response) {
  return function (params) {
    params.success(response);
  };
}
$.ajax = ajax_response('{ "title": "My dummy JSON" }');

В приведенном выше примере определите функцию ajax_response(), которая принимает некоторую строку JSON в качестве аргумента (или любое количество настраиваемых аргументов, полезных для имитации ответа) и возвращает функцию анонимного закрытия, которая будет назначена $.ajax as переопределение для модульного тестирования.

Анонимная функция принимает аргумент params, который будет содержать объект настроек, переданный функции $.ajax. И он использует аргумент (ы), переданный внешней функции, для имитации ответа с сервера. В этом примере он всегда имитирует успешный ответ от сервера, просто вызывая обратный вызов success и снабжая его фиктивным JSON.

Легко переконфигурировать...

function ajax_response(response, success) {
  return function (params) {
    if (success) {
      params.success(response);
    } else {
      params.error(response);
    }
  };
}

// Simulate success
$.ajax = ajax_response('{ "title": "My dummy JSON." }', true); 
doAsyncThing(); // Function that calls $.ajax

// Simulate error
$.ajax = ajax_response('{ "error": "Who is the dummy now?" }', false); 
doAsyncThing(); // Function that calls $.ajax

Ниже мы видим это в действии...

/* FUNCTION THAT MAKES AJAX REQUEST */
function doAsyncThing() {
  $.ajax({
    type: "POST",
    url: "somefile.php",
    // data: {…},
    success: function (results) {
      var json = $.parseJSON(results),
          html = $('#ids').html();
      $('#ids').html(html + '<br />' + json.id);
    }
  });
}

/* BEGIN MOCK TEST */
// CREATE CLOSURE TO RETURN DUMMY FUNCTION AND FAKE RESPONSE
function ajax_response(response) {
  return function (params) {
    params.success(response);
  };
}

var n = prompt("Number of AJAX calls to make", 10);

for (var i = 1; i <= n; ++i) {
  
  // OVERRIDE $.ajax WITH DUMMY FUNCTION AND FAKE RESPONSE
  $.ajax = ajax_response('{ "id": ' + i + ' }');
  doAsyncThing();
}
/* END MOCK TEST */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="ids">IDs:</p>

Ответ 4

Mock $.ajax при необходимости без нарушения jQuery

Ответы здесь хороши, но им нужна конкретная потребность в создании поддельного ответа на один вызов API, оставив все остальные вызовы API одинаковыми до тех пор, пока серверная служба не будет построена, поэтому я могу продолжить сбор данных в пользовательском интерфейсе.

Объект API использует $.ajax под капотом, поэтому вы можете вызвать метод API следующим образом:

api.products({ price: { $lt: 150, tags: ['nike', 'shoes'] } })
.done(function(json) {
  // do something with the data
})
.error(function(err) {
  // handle error
});

Этот метод выполняет трюк:

function mockAjax(options) {
  var that = {
    done: function done(callback) {
      if (options.success)
        setTimeout(callback, options.timeout, options.response);
      return that;
    },
    error: function error(callback) {
      if (!options.success)
        setTimeout(callback, options.timeout, options.response);
      return that;
    }
  };
  return that;
}

Затем переопределите один вызов api, не касаясь $.ajax:

api.products = function() {
  return mockAjax({
    success: true,
    timeout: 500,
    response: {
      results: [
        { upc: '123123', name: 'Jordans' },
        { upc: '4345345', name: 'Wind Walkers' }
      ]
    }
  });
};

https://jsfiddle.net/Lsf3ezaz/2/

Ответ 5

Посмотрите на документацию jQuery: вы увидите, что установка Ajax предоставляет ряд других условий, на которые протестированы. Если вы сделаете все, что указывает на ваш fakeAjaxSuccess, вы можете достичь своей цели.

В качестве альтернативы, оберните свой вызов $.ajax в свою собственную функцию и вызовите все вызовы, которые он просто вызывает обработчик событий с объектом fakeAjaxSuccess.

Ответ 6

Я думаю, что ссылка ниже должна помочь. что касается параметра, я не уверен, но это может быть.

$.fn.ajax.success =  function (){
  ///the rest goest here
}

Переопределить функцию jQuery.val()?