javascript Jasmine 的 toThrow 匹配器是否需要将参数包装在匿名函数中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9500586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 06:53:42  来源:igfitidea点击:

Does Jasmine's toThrow matcher require the argument to be wrapped in an anonymous function?

javascriptjasmine

提问by brahn

The documentation at https://github.com/pivotal/jasmine/wiki/Matchersincludes the following:

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

expect(function(){fn();}).toThrow(e);

As discussed in this question, the following does notwork because we want to pass a function object to expectrather than the result of calling fn()

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

expect(fn()).toThrow(e);

Question 1: Does the following work?

问题 1:以下是否有效?

expect(fn).toThrow(e);

Question 2: If I've defined an object thingwith a method doIt, does the following work?

问题 2:如果我已经thing用方法定义了一个对象,doIt以下是否有效?

expect(thing.doIt).toThrow(e);

(2a: if so, is there a way to pass arguments to the doItmethod?)

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

Empirically the answer seems to be yes but I don't trust my understanding of js scoping quite enough to be sure.

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

Thanks!

谢谢!

回答by Danyal Aytekin

We can do away with the anonymous function wrapper by using Function.bind, which was introduced in ECMAScript 5. This works in the latest versions of browsers, and you can patch older browsers by defining the function yourself. An example definition is given at the Mozilla Developer Network.

我们可以通过使用来取消匿名函数包装器Function.bind,它是在ECMAScript 5中引入的。这适用于最新版本的浏览器,您可以通过自己定义该功能来修补旧浏览器。Mozilla Developer Network给出了一个示例定义。

Here's an example of how bindcan be used with Jasmine.

这是一个如何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();
    });

});

The first argument provided to bindis used as the thisvariable when fis called. Any additional arguments are passed to fwhen it is invoked. Here 2is being passed as its first and only argument.

提供给的第一个参数在被调用时bind用作this变量f。任何其他参数在f调用时都会传递给它。Here2被作为它的第一个也是唯一的参数传递。

回答by Andreas K?berle

Lets take a look at the Jasmine source code:

让我们来看看Jasmine 源代码

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

This is the core part of the toThrowmethod. So all the method does is to execute the method you want to expect and check if a exception was thrown. So in your examples fnor thing.doItwill be called in the Jasmine will check if a error was thrown and if the type of this error is the one you passed into toThrow.

这是该toThrow方法的核心部分。所以这个方法所做的就是执行你想要的方法并检查是否抛出了异常。因此,在您的示例中fnthing.doIt将在 Jasmine 中调用时,将检查是否抛出错误以及此错误的类型是否与您传入的类型相同 toThrow

回答by Ustaman Sangat

Sadly, it seems that if I need to test a function that takes parameters, then I will need to wrap it with a function.

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

I would rather have preferred,

我宁愿选择,

expect(myTestFunction, arg1, arg2).toThrow();

But I am ok with explicitly doing

但我可以明确地做

expect(function(){myTestFunction(arg1, arg2);}).toThrow("some error");

FYI note that we can also use regex match on error:

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

expect(function (){myTestFunction(arg1, arg2);}).toThrowError(/err/);

回答by Neovibrant

If it is used like this:

如果像这样使用:

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

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

Then the function myTestFunction(arg)is executed before expect(...)and throw an exception before Jasmine has any chance of doing anything and it crashes the test resulting in an automatic failure.

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

If the function myTestFunction(arg)is not throwing anything (i.e. the code is not working as expected), then Jasmine would only get the resultof the function and check that for errors - which is incorrect.

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

To alleviate this, the code that is expected to throw an error is supposed to be wrapped in a function. This is passed to Jasmine which will execute it and check for the expected exception.

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

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

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