con jQuery, puede utilizar el objeto XHR que .ajax()
regresa como una promesa, por lo que puede añadir más controladores (véase más adelante) que sólo los individuales success
, complete
y error
los que se definen en las opciones. Entonces, si su función asíncrona puede devolver el objeto xhr, puede agregar manejadores específicos de la prueba.
En cuanto a la URL, eso es un poco más complicado. A veces configuré un servidor de Nodo muy simple en localhost, que solo sirve respuestas enlatadas que fueron copiadas del servidor real. Si ejecuta su suite de pruebas fuera del mismo servidor, sus URL solo deben ser rutas absolutas para acceder al servidor de prueba en lugar de al servidor de producción. Y también obtiene un registro de las solicitudes, como un servidor las ve. O puede hacer que el servidor de prueba envíe errores o respuestas erróneas a propósito, si desea ver cómo lo maneja el código.
Pero eso es, por supuesto, una solución bastante compleja. El más fácil sería definir sus URL en un lugar donde pueda redefinirlas desde el banco de pruebas. Por ejemplo:
/* in your code */
var X = function() {
this.fire = function() {
return $.ajax({ url: this.constructor.url, ... });
};
};
X.url = "someURL.php"; // the production url
/* in your tests */
X.url = "stub.php"; // redefine to the test url
Además, QUnit tiene una función asyncTest
, que llama stop()
para usted. Agregue un pequeño ayudante para realizar un seguimiento de cuándo volver a comenzar, y tiene una solución bastante buena.
Esto es lo que he hecho antes
// create a function that counts down to `start()`
function createAsyncCounter(count) {
count = count || 1; // count defaults to 1
return function() { --count || start(); };
}
// ....
// an async test that expects 2 assertions
asyncTest("testing something asynchronous", 2, function() {
var countDown = createAsyncCounter(1), // the number of async calls in this test
x = new X;
// A `done` callback is the same as adding a `success` handler
// in the ajax options. It's called after the "real" success handler.
// I'm assuming here, that `fire()` returns the xhr object
x.fire().done(function(data, status, jqXHR) {
ok(data.ok);
equal(data.value, "foobar");
}).always(countDown); // call `countDown` regardless of success/error
});
Básicamente countDown
es una función que cuenta regresiva a cero de lo que especifique, y luego llama start()
. En este caso, hay 1 llamada asincrónica, por lo que countDown
realizará una cuenta atrás desde allí. Y lo hará cuando finalice la llamada ajax, independientemente de cómo fue, ya que está configurada como una devolución de llamada always
.
Y como se dice que el asyncTest
espera 2 aserciones, informará de un error si nunca se llama a la devolución de llamada .done()
, ya que no se ejecutarán las aserciones. Entonces, si la llamada falla completamente, lo sabrá también. Si desea registrar algo por error, puede agregar una devolución de llamada .fail()
a la cadena de promesas.
Esto es genial. Muchas gracias :) –