我有问题让Chai的expect.to.throw在我的node.js应用程序的测试中工作。测试在抛出的错误上一直失败,但如果我在try和catch中包装测试用例并断言捕获的错误,它就可以工作。

是不是像我想的那样,期望。抛不掉?

it('should throw an error if you try to get an undefined property', function (done) {
  var params = { a: 'test', b: 'test', c: 'test' };
  var model = new TestModel(MOCK_REQUEST, params);

  // neither of these work
  expect(model.get('z')).to.throw('Property does not exist in model schema.');
  expect(model.get('z')).to.throw(new Error('Property does not exist in model schema.'));

  // this works
  try { 
    model.get('z'); 
  }
  catch(err) {
    expect(err).to.eql(new Error('Property does not exist in model schema.'));
  }

  done();
});

失败:

19 passing (25ms)
  1 failing

  1) Model Base should throw an error if you try to get an undefined property:
     Error: Property does not exist in model schema.

当前回答

我找到了一个很好的方法:

// The test, BDD style
it ("unsupported site", () => {
    The.function(myFunc)
    .with.arguments({url:"https://www.ebay.com/"})
    .should.throw(/unsupported/);
});


// The function that does the magic: (lang:TypeScript)
export const The = {
    'function': (func:Function) => ({
        'with': ({
            'arguments': function (...args:any) {
                return () => func(...args);
            }
        })
    })
};

它比我以前的版本更有可读性:

it ("unsupported site", () => {
    const args = {url:"https://www.ebay.com/"}; //Arrange
    function check_unsupported_site() { myFunc(args) } //Act
    check_unsupported_site.should.throw(/unsupported/) //Assert
});

其他回答

你必须传递一个函数。是这样的:

expect(model.get.bind(model, 'z')).to.throw('Property does not exist in model schema.');
expect(model.get.bind(model, 'z')).to.throw(new Error('Property does not exist in model schema.'));

你这样做的方式,你传递期望调用model.get('z')的结果。但是为了测试是否抛出了一些东西,您必须向expect传递一个函数,expect将调用它自己。上面使用的bind方法创建了一个新函数,该函数在被调用时会调用model。将这个set设置为model的值,并将第一个参数设置为'z'。

在这里可以找到bind的一个很好的解释。

来自doc…;)

因为你依赖于这个上下文:

当函数被.throw调用时丢失了什么 它没有办法知道这应该是什么

您必须使用以下选项之一:

将方法或函数调用包装到另一个函数中 绑定上下文 //将方法或函数调用包装到另一个函数中 Expect (function () {cat.meow();}) .to.throw ();//函数表达式 Expect (() => cat.meow()).to.throw();// ES6的箭头函数 //绑定上下文 期望(cat.meow.bind(猫).to.throw ();/ /绑定

正如这个答案所说,你也可以把你的代码包装在一个匿名函数中,就像这样:

expect(function(){
    model.get('z');
}).to.throw('Property does not exist in model schema.');

我找到了一个很好的方法:

// The test, BDD style
it ("unsupported site", () => {
    The.function(myFunc)
    .with.arguments({url:"https://www.ebay.com/"})
    .should.throw(/unsupported/);
});


// The function that does the magic: (lang:TypeScript)
export const The = {
    'function': (func:Function) => ({
        'with': ({
            'arguments': function (...args:any) {
                return () => func(...args);
            }
        })
    })
};

它比我以前的版本更有可读性:

it ("unsupported site", () => {
    const args = {url:"https://www.ebay.com/"}; //Arrange
    function check_unsupported_site() { myFunc(args) } //Act
    check_unsupported_site.should.throw(/unsupported/) //Assert
});

另一种可能的实现比.bind()解决方案更麻烦,但它有助于说明expect()需要一个为覆盖的函数提供this上下文的函数,您可以使用call(),例如:

期望(函数(){model.get。调用(模型、“z”);}).to.throw(“…”);