21

我一直在尝试编写一个处理错误的函数的文本,如果它是一个有效的错误,它就会被抛出,但如果不是,那么什么都不会抛出。问题是我似乎无法在使用时设置参数:

expect(handleError).to.throw(Error);

理想的情况是使用:

expect(handleError(validError)).to.throw(Error);

有没有办法实现这个功能?

函数代码:

function handleError (err) {
    if (err !== true) {
        switch (err) {
            case xxx:
            ...
        }
        throw "stop js execution";
    else {}
}

以及测试代码(未按预期工作):

it("should stop Javascript execution if the parameter isnt \"true\"", function() {
    expect(handleError).to.be.a("function");
    expect(handleError(true)).to.not.throw(Error);
    expect(handleError("anything else")).to.throw(Error);
});
4

4 回答 4

43

问题是您正在调用handleError,然后将结果传递给期望。如果handleError 抛出,那么expect 甚至不会被调用。

您需要推迟调用handleError,直到调用expect,以便expect 可以看到调用函数时发生的情况。幸运的是,这正是 expect 想要的:

expect(function () { handleError(true); }).to.not.throw();
expect(function () { handleError("anything else") }).to.throw("stop js execution");

如果你阅读了throw 的文档,你会看到相关的期望应该被传递给一个函数。

于 2013-10-03T02:58:06.383 回答
7

我今天遇到了同样的问题,并选择了这里没有提到的另一个解决方案:部分函数应用程序使用bind()

expect(handleError.bind(null, true)).to.not.throw();
expect(handleError.bind(null, "anything else")).to.throw("stop js execution");

这样做的好处是简洁,使用普通的旧 JavaScript,不需要额外的函数,this如果你的函数依赖于它,你甚至可以提供 的值。

于 2016-04-24T16:47:16.077 回答
1

正如 David Norman 所推荐的那样,将函数调用包装在 Lambda 中无疑是解决此问题的一种好方法。

但是,如果您正在寻找更具可读性的解决方案,您可以将其添加到您的测试实用程序中。此函数使用方法将您的函数包装在一个对象中withArgs,这允许您以更易读的方式编写相同的语句。理想情况下,这将内置到 Chai 中。

var calling = function(func) {
  return {
    withArgs: function(/* arg1, arg2, ... */) {
      var args = Array.prototype.slice.call(arguments);
      return function() {
        func.apply(null, args);
      };
    }
  };
};

然后像这样使用它:

expect(calling(handleError).withArgs(true)).to.not.throw();        
expect(calling(handleError).withArgs("anything else")).to.throw("stop js execution");

读起来像英文!

于 2016-01-04T11:35:25.613 回答
0

我使用带有 babel stage-2 预设的 ES2015,如果你这样做,你也可以使用它。

我采用了@StephenM347 解决方案并对其进行了一些修改,使其更短,更易读恕我直言:

let expectCalling = func => ({ withArgs: (...args) => expect(() => func(...args)) });

用法 :

expectCalling(handleError).withArgs(true).to.not.throw();        
expectCalling(handleError).withArgs("anything else").to.throw("stop js execution");

注意:如果您希望使用相同的用法(并坚持按expect()原样使用):

    let calling = func => ({ withArgs: (...args) => () => func(...args) });
于 2016-01-24T19:26:32.720 回答