柴:根据参数预期错误与否

时间:2013-09-30 14:40:34

标签: javascript mocha chai

我一直在尝试以一种方式处理错误的函数文本,如果它是有效错误,则抛出它,但如果不是,则不抛出任何内容。问题是我似乎无法在使用时设置参数:

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 个答案:

答案 0 :(得分:38)

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

你需要推迟调用handleError直到调用expect,这样expect才能看到调用函数时会发生什么。幸运的是,这是期望的:

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

如果您阅读documentation for throw,您会看到相关的期望应该传递给函数。

答案 1 :(得分:7)

我今天遇到了同样的问题,并选择了另一个未提及的解决方案:使用bind()的部分功能应用程序:

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

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

答案 2 :(得分:1)

按照David Norman的建议,在Lambda中包装函数调用肯定是解决此问题的一种好方法。

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

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");

它读起来像英文!

答案 3 :(得分:0)

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

我采用了@ 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) });