2012-05-10 14 views
20

Sto provando a scrivere alcuni test con Jasmine, ma ora ho un problema se ci sono dei codici asincroni in beforeEach.Come testare un metodo in Jasmine se il codice in `beforeEach` è asincrono?

Il codice di esempio si presenta come:

describe("Jasmine", function() { 

    var data ; 

    beforeEach(function(){ 
     console.log('Before each'); 
     getSomeDataFromRemote(function(res){ 
      data = res; 
     }); 
    }); 

    it("test1", function() { 
     expect(data).toBe(something); 
     console.log('Test finished'); 
    }); 

}); 

Si può vedere, nel beforeEach, voglio ottenere alcuni dati da remoto e assegnarlo al data in modo asincrono.

Ma nel test1, quando provo a verificare:

expect(data).toBe(something); 

I dati sono undefined, perché getSomeDataFromRemote non ha ancora finito.

Come ripararlo?

+0

So che Mocha può eseguire l'installazione asincrona, ma ho meno familiarità con Jasmine. Hai provato a utilizzare [costrutto async spec] (https://github.com/pivotal/jasmine/wiki/Asynchronous-specs) nel tuo 'beforeEach'? I documenti mostrano solo che vengono usati all'interno delle specifiche, ma potrebbero funzionare anche in 'beforeEach'. –

risposta

23

Proprio come la roba asincrono all'interno di un it è possibile utilizzare la runs e waitsFor nel beforeeach:

define('Jasmine' , function() { 
    var data ; 

    beforeEach(function(){ 
     runs(function() { 
      getSomeDataFromRemote(function(res){ 
       data = res; 
      }); 
     }); 

     waitsFor(function() { return !!data; } , 'Timed out', 1000); 
    }); 

    it("test1", function() { 
     runs(function() { 
       expect(data).toBe(something); 
     }); 
    }); 
}); 

Anche se ho intenzione di pensare che è perché questo era il codice di prova Penso che probabilmente si dovrebbe avere il getSomeDataFromRemote chiamata all'interno del vostro it come questo è in realtà ciò che si sta testando;)

si possono vedere alcuni esempi più grandi in alcuni test che ho scritto per un API asincrona qui: https://github.com/aaronpowell/db.js/blob/f8a1c331a20e14e286e3f21ff8cea8c2e3e57be6/tests/public/specs/open-db.js

+2

waits Per le corse è stato interrotto in Jasmine. Ora su, puoi usare done(). Spero che questo aiuti - http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support –

3

In questo caso, in genere stub la chiamata asincrona per rispondere immediatamente.

Non sono sicuro che lo abbiate visto o meno, ma here è una documentazione sui test asincroni con Jasmine.

+0

Ho appena controllato il tuo link, ma ancora non so come farlo nel mio caso. – Freewind

+0

Si esegue il wrapping della chiamata 'getSomeDataFromRemote' in una funzione' runs', oltre alle aspettative. Usi "attese" per fornire un intervallo di tempo sufficientemente lungo prima dell'esecuzione delle tue aspettative. E 'di sicuro, e può causare errori casuali. Questo è il motivo per cui ho appena interrotto la chiamata per tornare immediatamente. [Sinon.js] (http://sinonjs.org/) fornisce anche un certo aiuto nell'area di stub ajax se preferisci qualcosa di più dal metallo. – x1a4

+0

grazie, 'runs' e' waitsFor' è esattamente quello che sto cercando. Ma dal momento che @Slace mi ha dato un esempio funzionante e dettagliato, devo accettare la sua risposta. Spiacente ~ – Freewind

15

Jasmine 2.0

attenzione perché nella nuova Jasmine 2.0 questo sta per cambiare e sarà moca stile. È necessario utilizzare la funzione done() in beforeEach() e it(). Ad esempio, immagina di voler verificare se esiste una pagina e non è vuota, in un server LAMP, utilizzando jQuery $.get. In primo luogo è necessario aggiungere jQuery per il file SpecRunner.html, e nel file spec.js:

describe('The "index.php" should', function() { 
    var pageStatus; 
    var contents; 

    beforeEach(function (done) { 
     $.get('views/index.php', function (data, status) { 
      contents = data; 
      pageStatus = status; 
      done(); 
     }).fail(function (object, status) { 
      pageStatus = status; 
      done(); 
     }); 
    }); 

    it('exist', function(done) { 
     expect(status).toBe('success'); 
     done(); 
    }); 

    it('have content', function(done) { 
     expect(contents).not.toBe(''); 
     expect(contents).not.toBe(undefined); 
     done(); 
    }); 
}); 

Come si può vedere, si passa la funzione done() come parametro per beforeEach() e it(). Quando si esegue il test, it() non verrà avviato fino a quando done() è stato chiamato nella funzione beforeEach(), quindi non si avviano le aspettative finché non si ottiene la risposta dal server.

La pagina esiste

Se la pagina esiste catturiamo lo stato ei dati dalla risposta del server, e lo chiamiamo done(). Quindi controlliamo se lo stato è "successo" e se i dati non sono vuoti o indefiniti.

La pagina non esiste

Se la pagina non esiste catturiamo lo stato della risposta data dal server, e lo chiamiamo done(). Quindi controlliamo se lo stato non è "successo" e se i dati sono vuoti o indefiniti (ciò deve essere dovuto al fatto che il file non esiste).

+0

'done()' vale anche per progetti come [minijasminenode] (https://github.com/juliemr/minijasminenode) –

+0

che ho trovato primaTutto non supporta lo stile asincrono.le specifiche seguenti verranno eseguite prima che primaTutti chiamino il " done " – Kaicui

+2

Perché è' '' fatto''' passato nelle funzioni '' it''' e chiamato? Cosa potrebbe andare storto se fossero omessi dal '' it'''? – paulhhowells

Problemi correlati