Cómo probar el tipo de excepción lanzada en Jest

Resuelto bartsmykla asked hace 7 años • 23 respuestas

Estoy trabajando con un código en el que necesito probar el tipo de excepción lanzada por una función (¿es TypeError, ReferenceError, etc.?).

Mi marco de prueba actual es AVA y puedo probarlo como t.throwsmétodo de segundo argumento, como aquí:

it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', (t) => {
  const error = t.throws(() => {
    throwError();
  }, TypeError);

  t.is(error.message, 'UNKNOWN ERROR');
});

Comencé a reescribir mis pruebas en Jest y no encontré cómo hacerlo fácilmente. ¿Es siquiera posible?

bartsmykla avatar Sep 05 '17 01:09 bartsmykla
Aceptado

En Jest tienes que pasar una función a expect(function).toThrow(<blank or type of error>).

Ejemplo:

test("Test description", () => {
  const t = () => {
    throw new TypeError();
  };
  expect(t).toThrow(TypeError);
});

O si también desea comprobar si hay mensajes de error:

test("Test description", () => {
  const t = () => {
    throw new TypeError("UNKNOWN ERROR");
  };
  expect(t).toThrow(TypeError);
  expect(t).toThrow("UNKNOWN ERROR");
});

Si necesita probar una función existente si se ejecuta con un conjunto de argumentos, debe envolverla dentro de una función anónima en expect().

Ejemplo:

test("Test description", () => {
  expect(() => {http.get(yourUrl, yourCallbackFn)}).toThrow(TypeError);
});
PeterDanis avatar Sep 11 '2017 12:09 PeterDanis

Es un poco extraño, pero funciona y, en mi humilde opinión, se puede leer bien:

it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
  try {
      throwError();
      // Fail test if above expression doesn't throw anything.
      expect(true).toBe(false);
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});

El Catchbloque detecta su excepción y luego puede realizar la prueba en su archivo Error. Se necesita Strange expect(true).toBe(false);para fallar la prueba si Errorno se arroja lo esperado. De lo contrario, esta línea nunca será accesible ( Errordebería plantearse ante ellos).

@Kenny Body sugirió una mejor solución que mejora la calidad del código si usa expect.assertions():

it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
  expect.assertions(1);
  try {
      throwError();
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});

Vea la respuesta original con más explicaciones: Cómo probar el tipo de excepción lanzada en Jest

EDITAR 2022:

Para usar este enfoque y no activar no-conditional-expectla regla (si está usando eslint-plugin-jest), la documentación de esta regla sugiere usar un contenedor de errores:

class NoErrorThrownError extends Error {}

const getError = async <TError>(call: () => unknown): Promise<TError> => {
  try {
    await call();

    throw new NoErrorThrownError();
  } catch (error: unknown) {
    return error as TError;
  }
};

describe('when the http request fails', () => {
  it('includes the status code in the error', async () => {
    const error = await getError(async () => makeRequest(url));

    // check that the returned error wasn't that no error was thrown
    expect(error).not.toBeInstanceOf(NoErrorThrownError);
    expect(error).toHaveProperty('statusCode', 404);
  });
});

Ver: no-conditional-expectdocumentos

Paweł BB Drozd avatar Mar 27 '2018 12:03 Paweł BB Drozd