Jasmine的toThrow匹配器是否要求将参数包含在匿名函数中?

时间:2012-02-29 14:07:45

标签: javascript jasmine

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范围的理解足以确定。

谢谢!

4 个答案:

答案 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中调用fnthing.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