unitarios unitarias test pruebas integracion hacer como javascript testing node.js jasmine

javascript - test - pruebas unitarias en angular



¿Cómo escribir una prueba que espera que se lance un error en Jasmine? (8)

Estoy tratando de escribir una prueba para el marco de prueba Jasmine que espera un error. En este momento estoy usando una integración Jasmine Node.js de GitHub .

En mi módulo Nodo tengo el siguiente código:

throw new Error("Parsing is not possible");

Ahora trato de escribir una prueba que espera este error:

describe(''my suite...'', function() { [..] it(''should not parse foo'', function() { [..] expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible")); }); });

También probé Error() y algunas otras variantes y simplemente no puedo averiguar cómo hacer que funcione.


Como se mencionó anteriormente, una función debe pasarse a toThrow como es la función que está describiendo en su prueba: "Espero que esta función lance x"

expect(() => parser.parse(raw)) .toThrow(new Error(''Parsing is not possible''));

Si usa Jasmine-Matchers , también puede usar uno de los siguientes cuando se adapten a la situación;

// I just want to know that an error was // thrown and nothing more about it expect(() => parser.parse(raw)) .toThrowAnyError();

o

// I just want to know that an error of // a given type was thrown and nothing more expect(() => parser.parse(raw)) .toThrowErrorOfType(TypeError);


Para cualquier persona que aún pueda estar enfrentando este problema, para mí la solución publicada no funcionó y siguió generando este error: Error: Expected function to throw an exception. Más tarde, me di cuenta de que la función que esperaba emitir un error era una función asíncrona y esperaba que la promesa se rechazara y luego arrojara el error y eso es lo que estaba haciendo en mi código:

throw new Error(''REQUEST ID NOT FOUND'');

Y eso es lo que hice en mi prueba y funcionó:

it(''Test should throw error if request not found'', willResolve(() => { const promise = service.getRequestStatus(''request-id''); return expectToReject(promise).then((err) => { expect(err.message).toEqual(''REQUEST NOT FOUND''); }); }));


Para los amantes del coffeescript.

expect( => someMethodCall(arg1, arg2)).toThrow()


Reemplazo el emparejador de Jasmine con el siguiente: lo que le permite coincidir con la propiedad del nombre de la excepción o la propiedad del mensaje Para mí, esto hace que las pruebas sean más fáciles de escribir y menos frágiles, ya que puedo hacer lo siguiente:

throw { name: "NoActionProvided", message: "Please specify an ''action'' property when configuring the action map." }

y luego prueba con lo siguiente:

expect (function () { .. do something }).toThrow ("NoActionProvided");

Esto me permite modificar el mensaje de excepción más adelante sin interrumpir las pruebas, cuando lo importante es que arrojó el tipo esperado de excepción.

Este es el reemplazo para toThrow que permite esto:

jasmine.Matchers.prototype.toThrow = function(expected) { var result = false; var exception; if (typeof this.actual != ''function'') { throw new Error(''Actual is not a function''); } try { this.actual(); } catch (e) { exception = e; } if (exception) { result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected) || this.env.equals_(exception.name, expected)); } var not = this.isNot ? "not " : ""; this.message = function() { if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { return ["Expected function " + not + "to throw", expected ? expected.name || expected.message || expected : " an exception", ", but it threw", exception.name || exception.message || exception].join('' ''); } else { return "Expected function to throw an exception."; } }; return result; };


Sé que es más código pero también puedes hacer:

try do something @fail Error("should send a Exception") catch e expect(e.name).toBe "BLA_ERROR" expect(e.message).toBe ''Message''


Tu estas usando:

expect(fn).toThrow(e)

Pero si echa un vistazo a la función comentario (esperado es cadena):

294 /** 295 * Matcher that checks that the expected exception was thrown by the actual. 296 * 297 * @param {String} expected 298 */ 299 jasmine.Matchers.prototype.toThrow = function(expected) {

Supongo que probablemente deberías escribirlo así (usando lambda - función anónima):

expect(function() { parser.parse(raw); } ).toThrow("Parsing is not possible");

Esto se confirma en el siguiente ejemplo:

expect(function () {throw new Error("Parsing is not possible")}).toThrow("Parsing is not possible");

Douglas Crockford recomienda encarecidamente este enfoque, en lugar de usar "lanzar nuevo Error ()" (forma de creación de prototipos):

throw { name: "Error", message: "Parsing is not possible" }


Una solución más elegante que crear una función anónima cuyo único propósito es envolver otra, es usar la función de vinculación de es5. La función de vinculación crea una nueva función que, cuando se le llama, tiene su palabra clave configurada en el valor proporcionado, con una secuencia de argumentos dada que precede a cualquiera cuando se llama a la nueva función.

En lugar de:

expect(function () { parser.parse(raw, config); } ).toThrow("Parsing is not possible");

Considerar:

expect(parser.parse.bind(parser, raw, config)).toThrow("Parsing is not possible");

La sintaxis de vinculación le permite probar funciones con diferentes valores y, en mi opinión, hace que la prueba sea más legible. Consulte también: https://.com/a/13233194/1248889


debería pasar una función a la llamada de expect(...) . El código que tienes aquí:

// incorrect: expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));

está intentando llamar a parser.parse(raw) en un intento de pasar el resultado a expect(...) ,

Trate de usar una función anónima en su lugar:

expect( function(){ parser.parse(raw); } ).toThrow(new Error("Parsing is not possible"));