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

bra*_*ahn 37 javascript jasmine

https://github.com/pivotal/jasmine/wiki/Matchers上的文档包括以下内容:

expect(function(){fn();}).toThrow(e);
Run Code Online (Sandbox Code Playgroud)

正如在讨论这个问题,下面就无法工作,因为我们想要一个函数对象传递给expect,而不是调用的结果fn()

expect(fn()).toThrow(e);
Run Code Online (Sandbox Code Playgroud)

问题1:以下工作如何?

expect(fn).toThrow(e);
Run Code Online (Sandbox Code Playgroud)

问题2:如果我thing用方法定义了一个对象,doIt下面的工作是否正常?

expect(thing.doIt).toThrow(e);
Run Code Online (Sandbox Code Playgroud)

(2a:如果是这样,有没有办法将参数传递给doIt方法?)

根据经验,答案似乎是肯定的,但我不相信我对js范围的理解足以确定.

谢谢!

Dan*_*kin 48

我们可以使用ECMAScript 5Function.bind中引入的匿名函数包装器.这适用于最新版本的浏览器,您可以通过自己定义功能来修补旧浏览器.Mozilla开发者网络提供了一个示例定义.

这是一个如何bind与Jasmine一起使用的示例.

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();
    });

});
Run Code Online (Sandbox Code Playgroud)

提供的第一个参数在被调用时bind用作this变量f.f在调用它时,会传递任何其他参数.这2是作为第一个也是唯一一个参数传递的.


And*_*rle 6

让我们来看看Jasmine的源代码:

try {
  this.actual();
} catch (e) {
  exception = e;
}
if (exception) {
  result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
}
Run Code Online (Sandbox Code Playgroud)

这是该toThrow方法的核心部分.因此,所有方法都是执行您期望的方法并检查是否抛出了异常.因此,在您的示例中fnthing.doIt将在Jasmine中调用将检查是否抛出错误以及此错误的类型是否是您传入的错误类型 toThrow.


Ust*_*gat 5

可悲的是,似乎如果我需要测试一个带有参数的函数,那么我将需要用一个函数包装它。

我宁愿选择,

expect(myTestFunction, arg1, arg2).toThrow();
Run Code Online (Sandbox Code Playgroud)

但是我可以明确地做

expect(function(){myTestFunction(arg1, arg2);}).toThrow("some error");
Run Code Online (Sandbox Code Playgroud)

仅供参考,我们也可以对错误使用正则表达式匹配:

expect(function (){myTestFunction(arg1, arg2);}).toThrowError(/err/);
Run Code Online (Sandbox Code Playgroud)


Neo*_*ant 5

如果像这样使用:

expect(myTestFunction(arg)).toThrowAnyError(); // incorrect

然后在 Jasmine 有任何机会做任何事情之前myTestFunction(arg)执行该函数expect(...)并抛出异常,并且它使测试崩溃导致自动失败。

如果函数myTestFunction(arg)没有抛出任何东西(即代码没有按预期工作),那么 Jasmine 只会得到函数的结果并检查它是否有错误——这是不正确的。

为了缓解这种情况,应该将预期抛出错误的代码包装在一个函数中。这将传递给 Jasmine,后者将执行它并检查预期的异常。

expect(() => myTestFunction(arg)).toThrowAnyError(); // correct