2009-06-02 9 views
14

Sto cercando in QUnit per il test dell'unità JavaScript. Sono in una strana situazione in cui sto verificando il valore restituito dalla chiamata Ajax.QUnit con Ajax, QUnit supera i test falliti

Per il test seguente sto cercando intenzionalmente di fallirlo.

// test to check if the persons are returned! 
test("getPersons", function() { 
    getPersons(function(response) { 
    // persons = $.evalJSON(response.d); 
    equals("boo", "Foo", "The name is valid"); 
    }); 
}); 

ma finisce per passare tutto il tempo. Ecco il metodo getPersons che effettua la chiamata Ajax.

function getPersons(callback) { 
    var persons = null; 

    $.ajax({ 
    type: "POST", 
    dataType: "json", 
    data: {}, 
    contentType: "application/json", 
    url: "AjaxService.asmx/GetPersons", 
    success: function(response) { 
     callback(response); 
    } 
    }); 
} 
+0

vi consiglio di riempire anche nel "prevedere" il numero (secondo argomento di 'QUnit.test') in modo che sia più facile per la cattura quando non tutto viene chiamato nel tempo. Altrimenti potrebbe passare se 'start' viene chiamato troppo presto prima che tutte le asserzioni siano state inviate. – Krinkle

risposta

25

L'avvio e l'arresto utilizzando la libreria QUnit sembra funzionare!

// test to check if the persons are returned! 
test("getPersons", function() { 
    stop(); 
    getPersons(function(response) { 
    persons = $.evalJSON(response.d); 
    equals(persons[0].FirstName, "Mohammad"); 
    start(); 
    }); 
}); 
+1

Come @Goyuix ha detto che puoi anche usare 'asyncTest()' invece di 'test()' per evitare di chiamare il 'stop()' funzione e per rendere esplicito che si tratta di un test asincrono. –

2

ive eseguito alcuni test di qunit con ajax. non è carino la cosa migliore che potrei avere è fermare il test quando ajax viene attivato e ricominciare dal callback. (usando i metodi start() e stop()). Ciò significava una sola richiesta alla volta, ma potevo conviverci. Buona fortuna

+0

L'avvio e l'arresto sembrano funzionare! La soluzione è pubblicata nel post sottostante. Grazie! – azamsharp

+0

Ma mi chiedo perché il mio approccio sopra non funzionava. Potrei accedere alla risposta e tutto. Sembrava che gli uguali stessero fallendo! – azamsharp

+2

penso che a causa della natura asincrona di ajax, il test stava finendo prima che la risposta tornasse – mkoryak

13

Il vero problema qui non è la necessità di chiamare lo start() e stop() - in realtà si potrebbe ottenere nei guai con questo approccio, se non si è attenti a chiamare stop() di nuovo alla fine della richiamata se si dispone di ulteriori metodi .ajax(). Il che significa che ti ritrovi in ​​un pasticcio ringhioso di dover tenere traccia se tutte le callback sono state attivate per sapere se hai ancora bisogno di chiamare stop() di nuovo.

La radice del problema coinvolge il comportamento predefinito di richieste asincrone - e la soluzione più semplice è quello di rendere l'Ajax() richiesta avvenga in modo sincrono impostando il asincrona proprietà su false:

test("synchronous test", function() { 
    $.ajax({ 
    url:'Sample.asmx/Service', 
    async:false, 
    success: function(d,s,x) { ok(true, "Called synchronously"); } 
    }); 
}); 

Anche tuttavia, l'approccio migliore consiste nel consentire il comportamento asincrono e utilizzare il richiamo del metodo di prova corretto: asyncTest(). Secondo la documentazione "test asincroni sono in coda ed eseguire uno dopo l'altro. Equivalente a chiamare un test normale() e subito chiamando stop()."

asyncTest("a test", function() { 
    $.ajax({ 
    url: 'Sample.asmx/Service', 
    success: function(d,s,x) { 
     ok(true, "asynchronous PASS!"); 
     start(); 
    } 
    }); 
}); 
+0

asyncTest (nome, ...) è un metodo comodo per test (nome, funzione() {stop(); ...}). Nidificazione = cattiva idea. –

+0

@ Jörn - grazie per aver segnalato il nidificazione. Leggendo questa risposta non sono sicuro del motivo per cui l'ho avvolto in primo luogo, se non per illustrare che potresti. Ho scartato il metodo asyncTest per rendere più chiaro il modo in cui è destinato ad essere utilizzato. – Goyuix

3

C'è un sacco di test di qunit nel mio progetto . come:

module("comment"); 
    asyncTest("comment1", function() { 
     expect(6); 
     $.ajax({ 
     url: 'http://xxx.com/comment', 
     dataType: "json", 
     type: "GET", 
     timeout: 1000 
     }).done(function(data) { 
     ok(true, "loaded"); 
     ok(data.data.length>1, "array size"); 
     ok(data.total, "attr total"); 
     var c = data.data[0]; 
     ok(c.id, "attr c.id"); 
     ok(c.user_id, "attr c.user_id"); 
     ok(c.type == 4, "attr c.type equal 4"); 
     }).fail(function(x, text, thrown) { 
     ok(false, "ajax failed: " + text); 
     }).always(function(){ 
     start(); 
     }); 
    });