all javascript jquery ajax unit-testing testing

javascript - all - jquery replace html



Cómo falsificar la respuesta jquery.ajax()? (6)

Simula $ .ajax según sea necesario sin molestar jQuery

Las respuestas aquí son buenas, pero tenían una necesidad específica de generar una respuesta falsa a una única llamada de API, dejando todas las demás llamadas de la API iguales hasta que se construyó el servicio de back-end para que pueda seguir construyendo cosas en la interfaz de usuario.

El objeto API usa $ .ajax debajo del capó para que pueda llamar a un método API de esta manera:

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

Este método hace el truco:

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

A continuación, anule una sola llamada de API sin tocar $ .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/

Estoy escribiendo algunas pruebas QUnit para un JavaScript que hace llamadas AJAX.

Para el aislamiento, sobrescribo $.ajax para escribir la matriz de parámetros de una llamada AJAX a una variable. Esto funciona para probar cómo los métodos usan las funciones de AJAX, pero tengo dificultades para probar el controlador de éxito de $.load()

De la documentación en $.load() :

Cuando se detecta una respuesta exitosa (es decir, cuando textStatus es "exitoso" o "no modificado"), .load () establece el contenido HTML del elemento coincidente con los datos devueltos.

Así que he intentado devolver un objeto que contiene objetos con el mismo nombre que las variables para el controlador de éxito:

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

Pero este enfoque no ha funcionado.

¿Cómo puedo replicar el comportamiento de una llamada AJAX exitosa?


Use un cierre para anular $.ajax con una respuesta ficticia

Después de probar la respuesta aceptada y la respuesta publicada por user1634074 , ideé esta combinación simple y flexible de los dos.

En su forma más básica ...

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

En el ejemplo anterior, defina una función ajax_response() que acepte una cadena JSON como argumento (o cualquier número de argumentos personalizados útiles para simular una respuesta) y devuelve una función de cierre anónimo que se asignará a $.ajax como una anulación para examen de la unidad.

La función anónima acepta un argumento de params que contendrá el objeto de configuración pasado a la función $.ajax . Y usa los argumentos pasados ​​a la función externa para simular una respuesta del servidor. En este ejemplo, siempre simula una respuesta exitosa del servidor, simplemente invocando la success devolución de llamada y proporcionándole el JSON ficticio.

Es fácil de reconfigurar ...

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

A continuación podemos verlo en acción ...

/* 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>


Creo que el siguiente enlace debería ayudar. en cuanto a un parámetro, no estoy tan seguro, pero podría ser.

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

¿Anular la función jQuery .val ()?


Después de leer inspirado en @Robusto y @Val, encontré un método que funciona:

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

En lugar de plantear el evento desde cualquier código $ .ajax real o desencadenando cualquier evento, tengo mi objeto ajax falso para llamar a la función (que se pasa como un parámetro a $.ajax() ) como parte de mi función falsa.


Esta pregunta tiene algunos años y las nuevas versiones de jQuery han cambiado un poco.

Para hacer esto con Jasmin puedes probar el enfoque de Michael Falaga

Solución

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

Con Jasmine

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

Sin jazmín

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


Mira la documentación de jQuery: verás que la configuración de Ajax proporciona una serie de otras condiciones que se prueban. Si haces que todos apunten hacia tu FakeAjaxSuccess, podrías lograr tu objetivo.

De forma alternativa, ajuste su llamada $.ajax en su propia función y tenga las llamadas que fakeAjaxSuccess , simplemente llame a su controlador de eventos con el objeto fakeAjaxSuccess .