Как проверить тип исключенного исключения в Jest
Я работаю с некоторым кодом, где мне нужно проверить тип исключения, созданного функцией (это TypeError, ReferenceError и т.д.).
Моя текущая структура тестирования - AVA, и я могу проверить ее как второй аргумент метода t.throws
, например здесь:
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');
});
Я начал переписывать свои тесты на Jest и не мог найти, как легко это сделать. Возможно ли это?
Ответы
Ответ 1
В Jest вам нужно передать функцию в функцию ожидания (function).toThrow (пустое или тип ошибки).
Пример:
test("Test description", () => {
const t = () => {
throw new TypeError();
};
expect(t).toThrow(TypeError);
});
Если вам нужно проверить существующую функцию, выбрасывает ли она с помощью набора аргументов, вы должны обернуть ее внутри анонимной функции в expect().
Пример:
test("Test description", () => {
expect(() => {http.get(yourUrl, yourCallbackFn)}).toThrow(TypeError);
});
Ответ 2
Немного странно, но работает, и imho хорошо читается:
it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', () => {
try {
throwError();
// Fail test if above expression does not throw anything.
expect(true).toBe(false);
} catch (e) {
expect(e.message).toBe("UNKNOWN ERROR");
}
});
Блок Catch
перехватывает ваше исключение, затем вы можете проверить на поднятом Error
. Странный expect(true).toBe(false);
необходим, чтобы провалить ваш тест, если ожидаемый Error
не будет брошен. В противном случае эта строка никогда не будет достигнута (перед ними следует Error
).
ОБНОВЛЕНИЕ: @Kenny Body предлагает лучшее решение, которое улучшит качество кода, если вы используете expect.assertions()
it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', () => {
expect.assertions(1);
try {
throwError();
} catch (e) {
expect(e.message).toBe("UNKNOWN ERROR");
}
});
См. оригинальный ответ с дополнительными пояснениями: Как проверить тип сгенерированного исключения в Jest?
Ответ 3
Я использую немного более краткую версию:
expect(() => {
//code block that should throw error
}).toThrow(TypeError) //or .toThrow('expectedErrorMessage')
Ответ 4
Сам не пробовал, но я бы предложил использовать утверждение Jest toThrow. Итак, я думаю, ваш пример будет выглядеть примерно так:
it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', (t) => {
const error = t.throws(() => {
throwError();
}, TypeError);
expect(t).toThrowError('UNKNOWN ERROR');
//or
expect(t).toThrowError(TypeError);
});
Опять же, не проверял, но я думаю, что это должно работать.
Дайте мне знать, если это помогло.
Удачного кодирования!
Ответ 5
В Jest есть метод toThrow(error)
для проверки того, что функция выдает при вызове.
Итак, в вашем случае вы должны назвать это так:
expect(t).toThrowError(TypeError);
Документы
Ответ 6
Из моего (хотя и ограниченного) контакта с Jest я обнаружил, что expect().toThrow()
подходит, если вы хотите ТОЛЬКО проверить, выдана ли ошибка с конкретным сообщением:
expect(() => functionUnderTest()).toThrow(TypeError);
ИЛИ выдается ошибка определенного типа:
expect(() => functionUnderTest()).toThrow('Something bad happened!');
Если вы попытаетесь сделать оба, вы получите ложный положительный результат. Например, если ваш код выдает RangeError('Something bad happened!')
, этот тест пройдет:
expect(() => functionUnderTest()).toThrow(new TypeError('Something bad happened!'));
Ответ от bodolsog, который предлагает использовать попытку/улов, близок, но вместо того, чтобы ожидать, что истина будет ложной, чтобы гарантировать, что ожидаемые утверждения в улове достигнуты, вы можете вместо этого использовать expect.assertions(2)
в начале теста, где 2
количество ожидаемых утверждений. Я чувствую, что это более точно описывает цель теста.
Полный пример тестирования сообщения типа И об ошибке:
describe('functionUnderTest', () => {
it('should throw a specific type of error.', () => {
expect.assertions(2);
try {
functionUnderTest();
} catch (error) {
expect(error).toBeInstanceOf(TypeError);
expect(error).toHaveProperty('message', 'Something bad happened!');
}
});
});
Если functionUnderTest()
НЕ выдает ошибку, утверждения будут сброшены, но expect.assertions(2)
потерпит неудачу и тест не пройдёт.
Ответ 7
пытаться
expect(t).rejects.toThrow()
Ответ 8
В итоге я написал удобный метод для нашей библиотеки test-utils
/**
* Utility method to test for a specific error class and message in Jest
* @param {fn, expectedErrorClass, expectedErrorMessage }
* @example failTest({
fn: () => {
return new MyObject({
param: 'stuff'
})
},
expectedErrorClass: MyError,
expectedErrorMessage: 'stuff not yet implemented'
})
*/
failTest: ({ fn, expectedErrorClass, expectedErrorMessage }) => {
try {
fn()
expect(true).toBeFalsy()
} catch (err) {
let isExpectedErr = err instanceof expectedErrorClass
expect(isExpectedErr).toBeTruthy()
expect(err.message).toBe(expectedErrorMessage)
}
}
Ответ 9
Современный шут позволяет больше проверять отклоненную стоимость. Например:
const request = Promise.reject({statusCode: 404})
await expect(request).rejects.toMatchObject({ statusCode: 500 });
завершится ошибкой
Error: expect(received).rejects.toMatchObject(expected)
- Expected
+ Received
Object {
- "statusCode": 500,
+ "statusCode": 404,
}