Chai: expecting an error or not depending on a parameter [duplicate]

廉价感情. 提交于 2019-12-03 09:46:19

The problem is that you are calling handleError, then passing the result to expect. If handleError throws, then expect never even gets called.

You need to defer calling handleError until expect is called, so that expect can see what happens when the function is called. Fortunately, this is what expect wants:

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

If you read the documentation for throw, you'll see that the associated expect should be passed a function.

I ran into this same problem today and opted for another solution not mentioned here: partial function application using bind():

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

This has the benefit of being concise, using plain old JavaScript, requiring no extra functions and you can even provide the value of this should your function depend on it.

Wrapping the function call in a Lambda, as recommended by David Norman, is certainly one good way to solve this problem.

You might add this to your testing utilities, though, if you're looking for a more readable solution. This function wraps your function in an object with a method withArgs, which allows you to write the same statement in a more readable way. Ideally this would be built into Chai.

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

Then use it like:

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

It reads like english!

I use ES2015 with babel stage-2 preset, and if you do so, you can use this as well.

I took @StephenM347 solution and modified it a little to be shorter an even more readable IMHO :

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

Usage :

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

Note: if you wish the same usage (and stick to use expect() as is) :

    let calling = func => ({ withArgs: (...args) => () => func(...args) });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!