Pregunta

Estoy intentando escribir una prueba para la Test Framework Jasmine, que espera un error. Por el momento estoy usando un 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 que este error:

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

Me trató también Error() y algunas otras variantes y simplemente no puede encontrar la manera de hacer que funcione.

¿Fue útil?

Solución

que debe estar pasando una función en la llamada expect(...). El código que tenemos aquí:

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

En realidad está tratando de llamada parser.parse(raw) en un intento de pasar el resultado en expect(...),

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

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

Otros consejos

Está utilizando:

expect(fn).toThrow(e)

Pero si vas a tener una mirada sobre el comentario de función (es de esperar 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ía 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 firmemente este enfoque, en lugar de utilizar "throw new Error ()" (modo de prototipos):

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

sustituyo matcher toThrow de jazmín con los siguientes, que le permite adaptar en la propiedad el nombre de la excepción o la propiedad del mensaje. Para mí esto hace que las pruebas más fáciles de escribir y menos frágil, 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 romper las pruebas, cuando lo importante es que se lanzó 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;
};

Como se mencionó anteriormente, una función de las necesidades que se pasa a toThrow ya que es la función que usted describe en su ensayo: "espero que esta función para tirar x"

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

Si se utiliza Jasmine-comparadores también se puede utilizar una de las siguiente, siempre que se adaptan 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);

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

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

Para los amantes CoffeeScript

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

Para cualquier persona que todavía podrían enfrentarse a este problema, para mí la solución Posteado no funcionó y se mantuvo en lanzar este error: Error: Expected function to throw an exception. más tarde me di cuenta de que la función que yo estaba esperando para lanzar un error era una función asíncrona y estaba esperando la promesa de ser rechazado y luego tirar de error y eso es lo que estaba haciendo en mi código:

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

y eso es lo que he hecho 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');
                });
            }));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top