2012-02-29 8 views
33

La documentazione presso https://github.com/pivotal/jasmine/wiki/Matchers include quanto segue:Il matcher toThrow di Jasmine richiede che l'argomento sia racchiuso in una funzione anonima?

expect(function(){fn();}).toThrow(e); 

Come discusso nel this question, il seguente fa non lavoro perché vogliamo passare un oggetto funzione per expect piuttosto che il risultato della chiamata fn()

expect(fn()).toThrow(e); 

Domanda 1: Il seguente lavoro?

expect(fn).toThrow(e); 

Domanda 2: Se ho definito un oggetto thing con un metodo doIt, fa il seguente lavoro?

expect(thing.doIt).toThrow(e); 

(2 bis: se è così, c'è un modo per passare gli argomenti al metodo doIt?)

Empiricamente la risposta sembra essere sì, ma non mi fido mia comprensione di scoping js abbastanza per essere sicuro.

Grazie!

+0

Eventuali duplicati: http://stackoverflow.com/questions/4144686/jasmine-how-to-write-a-test-which-expects-an-error-to-be-thrown – Petrov

risposta

47

Possiamo eliminare il wrapper della funzione anonima usando Function.bind, che è stato introdotto in ECMAScript 5. Funziona con le ultime versioni dei browser e puoi applicare patch ai browser più vecchi definendo autonomamente la funzione. Una definizione di esempio è data allo Mozilla Developer Network.

Ecco un esempio di come è possibile utilizzare bind con Jasmine.

describe('using bind with jasmine', function() { 

    var f = function(x) { 
     if(x === 2) { 
      throw new Error(); 
     } 
    } 

    it('lets us avoid using an anonymous function', function() { 
     expect(f.bind(null, 2)).toThrow(); 
    }); 

}); 

Il primo argomento fornito bind viene utilizzato come variabile this quando f è chiamato. Eventuali argomenti aggiuntivi vengono passati a f quando viene richiamato. Qui 2 viene passato come primo e unico argomento.

+1

Questo funziona per me. Nota: ricorda il valore null in f.bind (oi tuoi parametri saranno uno solo nella funzione chiamata. L'ho perso la prima volta. (Ho collegato a questo per rendere più facile per me trovare: http: //geekswithblogs.net /Aligned/archive/2013/03/21/use-the-bind-method-for-jasmine-tothrow-tests.aspx) Grazie! – Aligned

6

consente di dare un'occhiata al Jasmine source code:

try { 
    this.actual(); 
} catch (e) { 
    exception = e; 
} 
if (exception) { 
    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); 
} 

Questa è la parte fondamentale del metodo toThrow. Quindi tutto il metodo è quello di eseguire il metodo che si desidera prevedere e verificare se è stata generata un'eccezione. Quindi nei tuoi esempi fn o thing.doIt verrà chiamato nel Jasmine controllerà se è stato generato un errore e se il tipo di questo errore è quello passato a toThrow.

+0

Tristemente , sembra che se ho bisogno di testare una funzione che prende parametri, allora avrò bisogno di avvolgerla con una funzione. –

4

Purtroppo, sembra che se ho bisogno di testare una funzione che richiede parametri, allora avrò bisogno di avvolgerla con una funzione.

avrei preferito preferito,

expect(myTestFunction, arg1, arg2).toThrow(); 

Ma io sono ok con il fare esplicitamente

expect(function(){myTestFunction(arg1, arg2);}).toThrow("some error"); 

FYI notare che possiamo anche utilizzare la corrispondenza regex in caso di errore:

expect(function(){myTestFunction(arg1, arg2);}).toThrowError(/err/); 
+0

Jasmine 2.0 ha toThrowError (/ regex /) –

0

Se viene usato in questo modo:

expect(myTestFunction(arg)).toThrowAnyError(); // incorrect

Poi la funzione myTestFunction(arg) viene eseguita prima expect(...) e un'eccezione prima di Jasmine ha qualche possibilità di fare qualsiasi cosa e si blocca il test con un conseguente fallimento automatico .

Se la funzione myTestFunction(arg) non è buttare nulla (vale a dire il codice non funziona come previsto), allora Jasmine sarebbe solo ottenere il risultato della funzione e verificare che per gli errori - che non è corretto.

Per alleviare questo problema, il codice che si prevede di generare un errore deve essere racchiuso in una funzione. Questo è passato a Jasmine che lo eseguirà e controllerà l'eccezione prevista.

expect(() => myTestFunction(arg)).toThrowAnyError(); // correct

Problemi correlati