¿Qué es "afirmar" en JavaScript?

263

¿Qué assertsignifica en JavaScript?

He visto algo como:

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

Y me gustaría saber qué hace el método assert().

frrlod
fuente

Respuestas:

367

No existe asserten JavaScript (todavía; se habla de agregar uno , pero está en una etapa temprana). Quizás esté utilizando alguna biblioteca que proporcione una. El significado habitual es arrojar un error si la expresión pasada a la función es falsa; Esto es parte del concepto general de verificación de afirmaciones . Por lo general, las aserciones (como se las llama) se usan solo en las versiones de "prueba" o "depuración" y se eliminan del código de producción.

Suponga que tiene una función que se supone que siempre debe aceptar una cadena. Desearía saber si alguien llamó a esa función con algo que no era una cadena. Entonces podrías hacer:

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

... donde assertarrojaría un error si la condición fuera falsa.

Una versión muy simple se vería así:

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

Mejor aún, haga uso del Errorobjeto si el motor de JavaScript lo admite (los más antiguos podrían no serlo), lo que tiene la ventaja de recopilar un seguimiento de pila y tal:

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

Incluso IE8 tiene Error(aunque no tiene la stackpropiedad, pero los motores modernos [incluido el IE moderno] sí).

TJ Crowder
fuente
66
... ¿optimista sobre los tipos en JS? Yo diría que esa es una de las peores razones para hacerlo assert.
cHao
137
@ cHao: Hay casos de uso válidos. Fue solo el primer ejemplo que me vino a la mente. El ejemplo no es el punto. El concepto de afirmaciones es el punto.
TJ Crowder
44
algo que he añadido a mi código dentro de la if(!condition)está fijando var throwError=true;a continuación, debugger;luego envolver la sección de tiro en una if(throwError). De esa manera, si tengo el depurador abierto, se romperá, y si lo deseo puedo establecerlo throwErroren falso y luego examinar todos los ámbitos mientras salgo.
Rick
8
@Rick si utiliza Chrome DevTools, simplemente puede habilitar "Pausa en excepciones no detectadas" en la pestaña Fuentes y se interrumpirá automáticamente en el throw. De esa manera no necesitas la debugger;declaración. Visita developer.chrome.com/devtools/docs/… para más información.
Vicky Chijwani
1
@machineghost: No veo cómo eso es "más simple", acabas de cambiar ifpor un operador condicional. De todos modos, en el mundo de hoy, no me molestaría en admitir motores que no tienen Error.
TJ Crowder
157

Si usa un navegador moderno o nodejs, puede usar console.assert(expression, object).

Para más información:

joaoprib
fuente
46
FYI, esto actúa más como console.errorsi el código continuara ejecutándose.
Daniel Sokolowski
10
@DanielSokolowski, Exactamente. console.assertno es tan bueno a menos que tenga el mismo comportamiento que throw.
Pacerier
23
La razón por la que la ejecución continúa console.assertes porque las aserciones no son funciones de manejo de errores. Están diseñados para la verificación de la corrección del código solo durante el desarrollo. Tradicionalmente, están completamente deshabilitados en entornos de producción para evitar que los sistemas en vivo terminen debido a algo trivial. El navegador se considera un entorno de producción, por lo console.assertque no finaliza la ejecución allí. Si confía en las aserciones para detener la ejecución, entonces debería usar un manejo de errores adecuado, ya que esto no es para lo que están hechas las aserciones.
Malvineous
8
@RonBurk: los diseñadores de idiomas decidieron "para qué están hechas las afirmaciones". En C ++ [una aserción] está diseñada para capturar errores de programación, no errores de usuario o de tiempo de ejecución, ya que generalmente se deshabilita después de que un programa sale de su fase de depuración. PHP dice que, como regla general, su código siempre debería poder funcionar correctamente si la comprobación de aserciones no está activada. La voz pasiva no estaba destinada a otorgar autoridad a una preferencia personal, sino a informar sobre lo que es una práctica general ampliamente aceptada.
Malvineous
44
@Don: Punto tomado pero solo estaba citando las páginas enlazadas. Creo que las afirmaciones deben tratarse como si pudieran deshabilitarse, aunque solo sea porque su código podría ser utilizado algún día por alguien que piense que es seguro hacerlo. Si las afirmaciones son críticas para su código, entonces creo que realmente deberían actualizarse a una verificación de errores adecuada en lugar de depender de un método de depuración que no siempre garantiza la finalización de la ejecución. ¡Sin mencionar que hacer que su código muera repetidamente en un entorno de producción cuando podría devolver un error y continuar podría causar más estrés del que vale!
Malvineous
29

Las otras respuestas son buenas: no hay una función de aserción integrada en ECMAScript5 (por ejemplo, JavaScript que funciona básicamente en todas partes), pero algunos navegadores se la proporcionan o tienen complementos que proporcionan esa funcionalidad. Si bien es probable que sea mejor usar una biblioteca bien establecida / popular / mantenida para esto, para fines académicos, una función de "afirmación del pobre" podría verse así:

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
iX3
fuente
Por cierto, uno podría modificar esto fácilmente para que solo arroje un error en entornos de desarrollo (por ejemplo, envolviendo otro si / agregando otro condicional) y de lo contrario no hace nada o solo imprime una advertencia. Personalmente, mi opinión es que las afirmaciones solo deben estar en el código de prueba (por ejemplo, verificar si los resultados esperados y reales coinciden); en el código de producción que deben o bien ser superfluo (garantizado correcta por diseño) y por lo tanto eliminado o sólo para la vigilancia de usuario de entrada / externa en cuyo caso pueden ser sustituidos por desinfección lógica y manejo de excepciones estándar (por ejemplo try, catch, throw)
IX3
8

assert()No es una función nativa de JavaScript. Es una función personalizada que alguien hizo. Tendrá que buscarlo en su página o en sus archivos y publicarlo para que cualquiera lo ayude a determinar lo que está haciendo.

Lápiz Violento
fuente
5

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

es para probar JavaScript. Sorprendentemente, con apenas cinco o seis líneas, este código proporciona un gran nivel de potencia y control sobre su código, durante las pruebas.

La función de aserción acepta dos parámetros:

resultado: un valor booleano, que hace referencia a si su prueba pasó o no

descripción: una breve descripción de su prueba.

La función de aserción simplemente crea un elemento de la lista, aplica una clase de "aprobado" o "fallido", dependiendo de si su prueba arrojó verdadero o falso, y luego agrega la descripción al elemento de la lista. Finalmente, ese bloque de codificación se agrega a la página. Es una locura simple, pero funciona perfectamente.

Amrendra
fuente
4

Aquí hay una implementación realmente simple de una función de aserción. Se necesita un valor y una descripción de lo que está probando.

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

Si el valor se evalúa como verdadero, pasa.

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

Si devuelve falso, falla.

assert (1===2, 'testing if 1=1');
joshpierro
fuente
1
El propósito de una aserción no es iniciar sesión en stdout a nivel de información, sino detener la ejecución del programa (generalmente provocando una excepción) e iniciar sesión en stderr si la aserción se evalúa como falsa.
Nuno André
4

Si la afirmación es falsa, se muestra el mensaje. Específicamente, si el primer argumento es falso, el segundo argumento (el mensaje de cadena) se registrará en la consola de herramientas del desarrollador. Si el primer argumento es verdadero, básicamente no pasa nada. Un ejemplo simple: estoy usando las Herramientas para desarrolladores de 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.');
Gato loco
fuente
3

Probablemente vino con una biblioteca de prueba que está usando parte de su código. Aquí hay un ejemplo de uno (es probable que no sea la misma biblioteca que está usando su código, pero muestra la idea general):

http://chaijs.com/guide/styles/#assert

Matt Browne
fuente
2

La palabra o función "afirmar" se usa principalmente para probar partes de la aplicación.

Las funciones de afirmación son una forma breve de indicar al programa que verifique la condición (también llamada "aserción") y si la condición no es Verdadera, arrojará un error.

Así que veamos cómo se vería en "código normal"

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

Con assertusted simplemente puede escribir:

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

En Javascript, no hay una assertfunción nativa , por lo que debe usar una de alguna biblioteca.

Para una introducción simple, puede consultar este artículo:

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

Espero que ayude.

Pavel
fuente
2

La aserción arroja un mensaje de error si el primer atributo es falso y el segundo atributo es el mensaje que se lanzará.

console.assert(condition,message);

Hay muchos comentarios que dicen que la aserción no existe en JavaScript, pero console.assert()es la función de aserción en JavaScript. La idea de la aserción es encontrar por qué / dónde ocurre el error.

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

Aquí, dependiendo del mensaje, puede encontrar cuál es el error. Estos mensajes de error se mostrarán en la consola en color rojo como si llamáramos console.error();
Para ver más funciones en la consola ejecutarconsole.log(console);

Rahul
fuente
1

Las respuestas anteriores se pueden mejorar en términos de rendimiento y compatibilidad.

Verifique una vez si el Errorobjeto existe, si no lo declara:

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

Luego, cada aserción verificará la condición y siempre arrojará un Errorobjeto

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

Tenga en cuenta que la consola no mostrará el número de línea de error real, sino la línea de la assertfunción, que no es útil para la depuración.

Karl.S
fuente
1

Si utiliza webpack, sólo puede utilizar la biblioteca afirmación Node.js . Aunque afirman que "no pretende ser una biblioteca de aserciones de propósito general", parece estar más que bien para las aserciones ad hoc, y parece que no existe ningún competidor en el espacio Node de todos modos (Chai está diseñado para pruebas unitarias).

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

Debe usar webpack o browserify para poder usar esto, por lo que obviamente esto solo es útil si ya están en su flujo de trabajo.

amoe
fuente
1

Además de otras opciones como console.assert o rodar la suya , puede usar invariante . Tiene un par de características únicas:

  • Admite mensajes de error formateados (usando un %sespecificador).
  • En entornos de producción (según lo determinado por el entorno Node.js o Webpack), el mensaje de error es opcional, permitiendo .js (ligeramente) más pequeños.
Josh Kelley
fuente
0

Como mencionó TJ, no hay asserten JavaScript. Sin embargo, hay un módulo de nodo llamado asir , que se utiliza principalmente para las pruebas . entonces, puede ver código como:

const assert = require('assert');
assert(5 > 7);
yuval.bl
fuente