摩卡/柴期望不会抛出抛出的错误

我有问题让柴的expect.to.throw工作在我的node.js应用程序的testing。 testing在抛出的错误上保持失败,但是如果我试着包装testing用例,并捕获和声明被捕获的错误,它就可以工作。

是否expect.to.throw不工作像我认为应该或什么?

 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. 

你必须传递一个函数来expect 。 喜欢这个:

 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.')); 

你这样做的方式,你正在传递expect调用model.get('z') 。 但是为了testing是否有东西被抛出,你必须传递一个函数来expect ,这个expect会自动调用。 上面使用的bind方法创build了一个新的函数,当被调用的model.getthis函数会调用model.get ,将this设置为model的值,第一个参数设置为'z'

有关bind一个很好的解释可以在这里find。

正如这个答案所说的 ,你也可以把你的代码封装在一个匿名函数中,如下所示:

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

如果您已经在使用ES6 / ES2015,那么您也可以使用箭头function。 这与使用普通的匿名函数基本相同,但较短。

 expect(() => model.get('z')).to.throw('Property does not exist in model schema.'); 

这个问题有很多很多的重复,包括没有提到柴断言库的问题。 以下是一起收集的基本信息:

断言必须调用该函数,而不是立即进行评估。

 assert.throws(xyz); // FAIL. xyz throws an exception, which immediately exits the // enclosing block, so assert.throw() not called. assert.throws(()=>xyz); // assert.throw() is called with a function, which only throws // when assert.throw executes the function. assert.throws(function () { xyz }); // if you cannot use ES6 at work function badReference() { xyz }; assert.throws(badReference); // for the verbose assert.throws(()=>model.get(z)); // the specific example given. homegrownAssertThrows(model.get, z); // a style common in Python, but not in JavaScript 

您可以使用任何断言库检查特定的错误:

节点

  assert.throws(() => xyz); assert.throws(() => xyz, ReferenceError); assert.throws(() => xyz, ReferenceError, /is not defined/); assert.throws(() => xyz, /is not defined/); assert.doesNotThrow(() => 42); assert.throws(() => xyz, Error); assert.throws(() => model.get.z, /Property does not exist in model schema./) 

应该

  should.throws(() => xyz); should.throws(() => xyz, ReferenceError); should.throws(() => xyz, ReferenceError, /is not defined/); should.throws(() => xyz, /is not defined/); should.doesNotThrow(() => 42); should.throws(() => xyz, Error); should.throws(() => model.get.z, /Property does not exist in model schema./) 

柴期待

  expect(() => xyz).to.throw(); expect(() => xyz).to.throw(ReferenceError); expect(() => xyz).to.throw(ReferenceError, /is not defined/); expect(() => xyz).to.throw(/is not defined/); expect(() => 42).not.to.throw(); expect(() => xyz).to.throw(Error); expect(() => model.get.z).to.throw(/Property does not exist in model schema./); 

您必须处理“逃避”testing的例外

 it('should handle escaped errors', function () { try { expect(() => xyz).not.to.throw(RangeError); } catch (err) { expect(err).to.be.a(ReferenceError); } }); 

起初这可能会让人感到困惑。 就像骑自行车一样,只要点击一下就会“点击”。