Che cos'è "assert" in JavaScript?


263

Cosa assertsignifica in JavaScript?

Ho visto qualcosa di simile:

assert(function1() && function2() && function3(), "some text");

E vorrei sapere cosa fa il metodo assert().

Risposte:


367

Non c'è assertJavaScript (ancora; si parla di aggiungerne uno , ma è in una fase iniziale). Forse stai usando una libreria che ne fornisce una. Il solito significato è generare un errore se l'espressione passata nella funzione è falsa; questo fa parte del concetto generale di controllo delle asserzioni . Solitamente le asserzioni (come vengono chiamate) vengono utilizzate solo nelle build "testing" o "debug" e rimosse dal codice di produzione.

Supponiamo che tu abbia una funzione che dovrebbe sempre accettare una stringa. Vorresti sapere se qualcuno ha chiamato quella funzione con qualcosa che non era una stringa. Quindi potresti fare:

assert(typeof argumentName === "string");

... dove assertverrebbe generato un errore se la condizione fosse falsa.

Una versione molto semplice sarebbe simile a questa:

function assert(condition, message) {
    if (!condition) {
        throw message || "Assertion failed";
    }
}

Meglio ancora, usa l' Erroroggetto se il motore JavaScript lo supporta (quelli davvero vecchi potrebbero non farlo), il che ha il vantaggio di raccogliere una traccia dello stack e simili:

function assert(condition, message) {
    if (!condition) {
        message = message || "Assertion failed";
        if (typeof Error !== "undefined") {
            throw new Error(message);
        }
        throw message; // Fallback
    }
}

Anche IE8 ha Error(anche se non ha la stackproprietà, ma i motori moderni [incluso IE moderno] lo fanno).


6
... stai diventando arrogante sui tipi in JS? Direi che è uno dei peggiori motivi per farlo assert.
cHao,

137
@cHao: ci sono casi d'uso validi. È stato solo il primo esempio che mi è venuto in mente. L'esempio non è il punto. Il concetto di affermazioni è il punto.
TJ Crowder

4
qualcosa che ho aggiunto al mio codice all'interno del if(!condition)è l'impostazione var throwError=true;quindi debugger;poi avvolgere la sezione tiro in una if(throwError). In questo modo, se ho il debugger aperto, si romperà e, se lo desidero, posso impostare throwErrorsu false e quindi esaminare tutti gli ambiti mentre esco.
Rick,

8
@Rick se usi Chrome DevTools, puoi semplicemente abilitare "Pausa su eccezioni non rilevate" nella scheda Sorgenti e si interromperà automaticamente in throw. In questo modo non hai bisogno debugger;dell'affermazione. Vedi developer.chrome.com/devtools/docs/… per ulteriori informazioni.
Vicky Chijwani,

1
@machineghost: non vedo come sia "più semplice", hai appena scambiato ifcon un operatore condizionale. Ad ogni modo, nel mondo di oggi, non mi preoccuperei di supportare motori che non hanno Error.
TJ Crowder,

157

Se si utilizza un browser moderno o nodejs, è possibile utilizzare console.assert(expression, object).

Per maggiori informazioni:


46
Cordiali saluti, questo si comporta più come console.errornel fatto che il codice continua a essere eseguito.
Daniel Sokolowski,

10
@DanielSokolowski, esattamente. console.assertnon è così buono a meno che non abbia lo stesso comportamento di throw.
Pacerier,

23
Il motivo per cui l'esecuzione continua dopo console.assertè perché le asserzioni non sono funzioni di gestione degli errori. Sono progettati per il controllo della correttezza del codice solo durante lo sviluppo. Tradizionalmente sono completamente disabilitati negli ambienti di produzione per evitare che i sistemi live terminino a causa di qualcosa di banale. Il browser è considerato un ambiente di produzione, quindi console.assertnon termina l'esecuzione lì. Se si fa affidamento sulle asserzioni per interrompere l'esecuzione, è necessario utilizzare invece la corretta gestione degli errori, poiché non è questo il significato delle asserzioni.
Malvineous,

8
@RonBurk: i progettisti linguistici hanno deciso "a cosa servono le asserzioni". In C ++ [un'asserzione] è progettata per catturare errori di programmazione, non errori dell'utente o di runtime, poiché è generalmente disabilitato dopo che un programma è uscito dalla sua fase di debug. PHP dice Come regola empirica il tuo codice dovrebbe sempre essere in grado di funzionare correttamente se il controllo delle asserzioni non è attivato. La voce passiva non aveva lo scopo di dare autorità a una preferenza personale, ma piuttosto di riferire ciò che è ampiamente accettato dalla pratica generale.
Malvineous

4
@Don: punto preso ma stavo solo citando dalle pagine collegate. Credo che le asserzioni debbano essere trattate come se fossero disabilitabili, anche solo perché un giorno il tuo codice potrebbe essere usato da qualcuno che pensa che sia sicuro farlo. Se le asserzioni sono fondamentali per il tuo codice, penso che dovrebbero davvero essere aggiornate al corretto controllo degli errori piuttosto che fare affidamento su un metodo di debug che non è sempre garantito per terminare l'esecuzione. Per non parlare del fatto che il fatto che il tuo codice muoia ripetutamente in un ambiente di produzione quando potrebbe semplicemente restituire un errore e continuare potrebbe causare più stress di quanto valga la pena!
Malvineous

29

Le altre risposte sono buone: non esiste una funzione di asserzione integrata in ECMAScript5 (ad es. JavaScript che funziona praticamente ovunque) ma alcuni browser te lo danno o hanno componenti aggiuntivi che forniscono tale funzionalità. Mentre è probabilmente meglio usare una libreria ben consolidata / popolare / mantenuta per questo, per scopi accademici una funzione di "affermazione di un uomo povero" potrebbe assomigliare a questa:

const assert = function(condition, message) {
    if (!condition)
        throw Error('Assert failed: ' + (message || ''));
};

assert(1 === 1); // Executes without problem
assert(false, 'Expected true');
// Yields 'Error: Assert failed: Expected true' in console


A proposito, si potrebbe facilmente modificare questo in modo che generi solo un errore negli ambienti di sviluppo (ad es. Avvolgendo un altro se / aggiungendo un altro condizionale) e altrimenti non fa nulla o stampa solo un avviso. Personalmente, la mia opinione è che le affermazioni dovrebbero essere solo nel codice di test (ad esempio, verificare se i risultati attesi e reali corrispondono); nel codice di produzione dovrebbero essere superflui (garantiti in base alla progettazione) e quindi rimossi o solo per proteggere l'utente / input esterno, nel qual caso possono essere sostituiti mediante la sanitizzazione della logica e la gestione delle eccezioni standard (ad es try. catch, throw)
iX3

8

assert()non è una funzione javascript nativa. È una funzione personalizzata creata da qualcuno. Dovrai cercarlo sulla tua pagina o nei tuoi file e pubblicarlo per chiunque possa aiutare a determinare cosa sta facendo.


5

controlla questo: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/

è per testare JavaScript. Sorprendentemente, a sole cinque o sei righe, questo codice fornisce un grande livello di potenza e controllo sul codice, durante i test.

La funzione assert accetta due parametri:

risultato: un valore booleano che indica se il test è stato superato o meno

descrizione: una breve descrizione del test.

La funzione assert quindi crea semplicemente un elemento dell'elenco, applica una classe di "pass" o "fail", a seconda che il test abbia restituito vero o falso, quindi aggiunge la descrizione all'elemento dell'elenco. Infine, quel blocco di codice è aggiunto alla pagina. È follemente semplice, ma funziona perfettamente.


4

Ecco un'implementazione davvero semplice di una funzione assert. Prende un valore e una descrizione di ciò che stai testando.

 function assert(value, description) {
        var result = value ? "pass" : "fail";
        console.log(result + ' - ' +  description); 
    };

Se il valore restituisce true, passa.

assert (1===1, 'testing if 1=1');  

Se restituisce false, fallisce.

assert (1===2, 'testing if 1=1');

1
Lo scopo di un'asserzione non è quello di accedere a stdout a livello di informazioni, ma di interrompere l'esecuzione del programma (di solito sollevando un'eccezione) e di accedere a stderr se l'asserzione viene valutata su false.
Nuno André,

4

Se l'asserzione è falsa, viene visualizzato il messaggio. In particolare, se il primo argomento è falso, il secondo argomento (il messaggio stringa) verrà registrato nella console degli strumenti di sviluppo. Se il primo argomento è vero, praticamente non accade nulla. Un semplice esempio: sto utilizzando Strumenti per gli sviluppatori di Google:

var isTrue = true;
var isFalse = false;
console.assert(isTrue, 'Equals true so will NOT log to the console.');
console.assert(isFalse, 'Equals false so WILL log to the console.');


2

La parola o la funzione "assert" è utilizzata principalmente per testare parti dell'applicazione.

Le funzioni di asserzione sono un modo breve per istruire il programma a controllare la condizione (anche chiamata "asserzione") e se la condizione non è vera, genererà un errore.

Quindi vediamo come sarebbe nel "codice normale"

if (typeof "string" === "array") { throw Error('Error: "string" !== "array"'); }

Con assertte puoi semplicemente scrivere:

assert(typeof "string" === "array")

In Javascript, non esiste una assertfunzione nativa , quindi devi usarne una da alcune librerie.

Per una semplice introduzione, puoi consultare questo articolo:

http://fredkschott.com/post/2014/05/nodejs-testing-essentials/

Spero possa essere d'aiuto.


2

L'asserzione genera un messaggio di errore se il primo attributo è falso e il secondo attributo è il messaggio da lanciare.

console.assert(condition,message);

Ci sono molti commenti che affermano che l'asserzione non esiste in JavaScript ma console.assert()è la funzione di asserzione in JavaScript L'idea di asserzione è di scoprire perché / dove si verifica il bug.

console.assert(document.getElementById("title"), "You have no element with ID 'title'");
console.assert(document.getElementById("image"), "You have no element with ID 'image'");

Qui a seconda del messaggio puoi trovare qual è il bug. Questi messaggi di errore verranno visualizzati sulla console in colore rosso come se avessimo chiamato console.error();
Per vedere l'esecuzione di più funzioni nella consoleconsole.log(console);


1

Le risposte precedenti possono essere migliorate in termini di prestazioni e compatibilità.

Controlla una volta se l' Erroroggetto esiste, in caso contrario dichiaralo:

if (typeof Error === "undefined") {
    Error = function(message) {
        this.message = message;
    };
    Error.prototype.message = "";
}

Quindi, ogni asserzione verificherà la condizione e lancerà sempre un Erroroggetto

function assert(condition, message) {
    if (!condition) throw new Error(message || "Assertion failed");
}

Tieni presente che la console non visualizzerà il numero della riga di errore reale, ma la riga della assertfunzione, che non è utile per il debug.


1

Se si utilizza webpack, si può semplicemente utilizzare la libreria asserzione node.js . Sebbene affermino che "non è destinato a essere una libreria di asserzioni per scopi generici", sembra essere più che OK per asserzioni ad hoc, e sembra comunque che non vi siano concorrenti nello spazio Node (Chai è progettato per i test unitari).

const assert = require('assert');
...
assert(jqXHR.status == 201, "create response should be 201");

Devi usare webpack o browserify per poterlo usare, quindi ovviamente questo è utile solo se quelli sono già nel tuo flusso di lavoro.


1

Oltre ad altre opzioni come console.assert o il tuo roll , puoi usare invariant . Ha un paio di caratteristiche uniche:

  • Supporta messaggi di errore formattati (usando un %sidentificatore).
  • Negli ambienti di produzione (come determinato dall'ambiente Node.js o Webpack), il messaggio di errore è facoltativo, consentendo .js (leggermente) più piccoli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.