https://github.com/pivotal/jasmine/wiki/Matchers处的文档包括以下内容:
expect(function(){fn();}).toThrow(e);
如this question中所述,以下不工作,因为我们希望将函数对象传递给expect
,而不是调用fn()
<的结果/ p>
expect(fn()).toThrow(e);
问题1:以下工作是否有效?
expect(fn).toThrow(e);
问题2:如果我使用方法thing
定义了对象doIt
,请执行以下操作吗?
expect(thing.doIt).toThrow(e);
(2a:如果是这样,有没有办法将参数传递给doIt
方法?)
根据经验,答案似乎是肯定的,但我不相信我对js范围的理解足以确定。
谢谢!
答案 0 :(得分:48)
我们可以使用Function.bind
中引入的bind
取消匿名函数包装器。这适用于最新版本的浏览器,您可以通过自己定义功能来修补旧浏览器。 ECMAScript 5上给出了一个示例定义。
以下是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();
});
});
如何与Jasmine一起使用的示例。
bind
this
提供的第一个参数在调用f
时用作f
变量。调用时,任何其他参数都会传递给2
。这里{{1}}作为第一个也是唯一的参数被传递。
答案 1 :(得分:6)
让我们看看Jasmine source code:
try {
this.actual();
} catch (e) {
exception = e;
}
if (exception) {
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
}
这是toThrow
方法的核心部分。因此,所有方法都是执行您期望的方法并检查是否抛出了异常。因此,在您的示例中,将在Jasmine中调用fn
或thing.doIt
来检查是否抛出了错误以及此错误的类型是否是您传入toThrow
的错误类型。
答案 2 :(得分:5)
可悲的是,似乎如果我需要测试一个带参数的函数,那么我需要用函数包装它。
我宁愿选择,
expect(myTestFunction, arg1, arg2).toThrow();
但我明确地做了
expect(function(){myTestFunction(arg1, arg2);}).toThrow("some error");
仅供参考,我们也可以在错误时使用正则表达式匹配:
expect(function (){myTestFunction(arg1, arg2);}).toThrowError(/err/);
答案 3 :(得分:2)
如果像这样使用:
expect(myTestFunction(arg)).toThrowAnyError(); // incorrect
然后函数myTestFunction(arg)
在expect(...)
之前执行,并在Jasmine有机会做任何事情之前抛出异常,它会导致测试崩溃,导致自动失败。
如果函数myTestFunction(arg)
没有抛出任何东西(即代码没有按预期工作),那么Jasmine只会得到函数的结果并检查错误 - 哪个是不正确的。
为了缓解这种情况,预计会抛出错误的代码应该包含在函数中。这将传递给Jasmine,它将执行它并检查预期的异常。
expect(() => myTestFunction(arg)).toThrowAnyError(); // correct