Содержит ли Jasmine toThrow matcher аргумент, который должен быть обернут анонимной функцией?
Документация на https://github.com/pivotal/jasmine/wiki/Matchers включает в себя следующее:
expect(function(){fn();}).toThrow(e);
Как обсуждалось в этом вопросе, следующее работает not, потому что мы хотим передать объект функции expect
, а не результат вызова fn()
expect(fn()).toThrow(e);
Вопрос 1: Работает ли следующая работа?
expect(fn).toThrow(e);
Вопрос 2: Если я определил объект thing
с помощью метода doIt
, работает ли следующее?
expect(thing.doIt).toThrow(e);
(2a: если да, есть ли способ передать аргументы методу doIt
?)
Эмпирически ответ кажется да, но я не доверяю своему пониманию js охвата достаточно, чтобы быть уверенным.
Спасибо!
Ответы
Ответ 1
Мы можем покончить с анонимной оболочкой функции, используя Function.bind
, который был представлен в ECMAScript 5. Это работает в последних версиях браузеров, и вы можете исправить старые браузеры, определив функцию самостоятельно. Примерное определение приведено в Mozilla Developer Network.
Вот пример того, как bind
можно использовать с Жасмином.
describe('using bind with jasmine', function() {
var f = function(x) {
if(x === 2) {
throw new Error();
}
}
it('lets us avoid using an anonymous function', function() {
expect(f.bind(null, 2)).toThrow();
});
});
Первый аргумент, предоставляемый bind
, используется как переменная this
, когда вызывается f
. Любые дополнительные аргументы передаются в f
при его вызове. Здесь 2
передается как его первый и единственный аргумент.
Ответ 2
Давайте посмотрим на Исходный код Jasmine:
try {
this.actual();
} catch (e) {
exception = e;
}
if (exception) {
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
}
Это основная часть метода toThrow
. Таким образом, весь метод - это выполнить метод, который вы хотите ожидать, и проверить, было ли исключено исключение. Поэтому в ваших примерах fn
или thing.doIt
будет вызываться в Jasmine, будет проверять, была ли ошибка выбрана, и если тип этой ошибки является тем, который вы передали в toThrow
.
Ответ 3
К сожалению, мне кажется, что если мне нужно проверить функцию, которая принимает параметры, тогда мне нужно будет обернуть ее с помощью функции.
Я предпочел бы,
expect(myTestFunction, arg1, arg2).toThrow();
Но я в порядке с явным выполнением
expect(function(){myTestFunction(arg1, arg2);}).toThrow("some error");
FYI отметим, что мы также можем использовать соответствие регулярных выражений при ошибке:
expect(function (){myTestFunction(arg1, arg2);}).toThrowError(/err/);