【问题标题】:Testing for errors thrown in Mocha [duplicate]测试 Mocha 中抛出的错误 [重复]
【发布时间】:2013-02-04 16:26:35
【问题描述】:

我希望能在这个问题上找到一些帮助。我正在尝试为我正在编写的应用程序编写测试。我已将问题提炼为以下示例代码。我想测试是否引发了错误。我使用 Testacular 作为测试运行程序,以 mocha 作为框架,chai 作为断言库。测试运行,但测试失败,因为抛出了错误!非常感谢任何帮助!

function iThrowError() {
    throw new Error("Error thrown");
}

var assert = chai.assert,
    expect = chai.expect;
describe('The app', function() {
    describe('this feature', function() {
        it("is a function", function(){
            assert.throw(iThrowError(), Error, "Error thrown");
        });
    });
});

【问题讨论】:

  • 好吧,我发现如果我将断言从 assert.throw(iThrowError(), Error, "Error thrown"); 更改为 expect(iThrowError).to.throw(); 这会使测试通过,但它似乎不允许检查是否有任何特定错误,我认为会更有用。我想我仍然缺少一些东西。

标签: javascript testing mocha.js chai


【解决方案1】:

你没有以正确的方式将你的函数传递给assert.throws()

assert.throws() 函数需要一个函数作为其第一个参数。在您的代码中,您正在调用 iThrowError 并在调用 assert.throws() 时传递其返回值。

基本上,改变这个:

assert.throws(iThrowError(), Error, "Error thrown");

到这里:

assert.throws(iThrowError, Error, "Error thrown");

应该可以解决你的问题。

带参数:

assert.throws(() => { iThrowError(args) }, Error);

assert.throws(function() { iThrowError(args) }, Error, /Error thrown/);

【讨论】:

  • 如果我想将参数传递给函数怎么办?有没有办法做到这一点?
  • Glen,要将参数传递给您的函数,请尝试包装一个函数:assert.throw(function() { iThrowError(args) }, Error)
  • 我在使用 Chai expect 时遇到了类似的问题,我实际上是在调用函数而不是传递引用。此解决方案解决了问题,谢谢!
  • @GlenSelle 我使用绑定来执行此操作。例如```函数打印(输入){console.log(输入)}; var foo = print.bind(undefined,"my string"); foo() // 打印“我的字符串” ``` developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 您的最后 2 个代码句子中有错字。应该是assert.throws。而不是assert.throw 所以正确的代码是:assert.throws(() => { iThrowError(args) }, Error); assert.throws(function() { iThrowError(args) }, Error, /Error thrown/);
【解决方案2】:

添加到the top answer,如果你需要调用你的函数作为测试的一部分(即你的函数应该只在传递某些参数时抛出错误),你可以将你的函数调用包装在一个匿名函数中,或者,在 ES6+ 中,您可以在箭头函数表达式中传递您的函数。

// Function invoked with parameter.
// TEST FAILS. DO NOT USE.
assert.throws(iThrowError(badParam), Error, "Error thrown"); // WRONG!

// Function invoked with parameter; wrapped in anonymous function for test.
// TEST PASSES.
assert.throws(function () { iThrowError(badParam) }, Error, "Error thrown");

// Function invoked with parameter, passed as predicate of ES6 arrow function.
// TEST PASSES.
assert.throws(() => iThrowError(badParam), Error, "Error thrown");

而且,为了彻底起见,这里有一个更字面的版本:

// Explicit throw statement as parameter. (This isn't even valid JavaScript.)
// TEST SUITE WILL FAIL TO LOAD. DO NOT USE, EVER.
assert.throws(throw new Error("Error thrown"), Error, "Error thrown"); // VERY WRONG!

// Explicit throw statement wrapped in anonymous function.
// TEST PASSES.
assert.throws(function () { throw new Error("Error thrown") }, Error, "Error thrown");

// ES6 function. (You still need the brackets around the throw statement.)
// TEST PASSES.
assert.throws(() => { throw new Error("Error thrown") }, Error, "Error thrown");

【讨论】:

  • 重复接受的答案有什么意义?
  • @Louis 这不是重复。公认的答案是将函数作为引用传递,并且调用该函数。正如我在答案顶部所说的那样,如果测试需要调用,我将解释如何实际调用该函数作为测试的一部分。
【解决方案3】:

我看到您能够解决您的问题,但无法检查特定错误。要使用 Chai 的 expect/should 语法,您可以使用来自 throw() 不同签名的参数:

@param{ ErrorConstructor } constructor
@param{ String | RegExp } expectederror message
@param{ String } message _optional_

在您的示例中,您应该能够使用以下任一方法:

expect(iThrowError).to.throw(/Error thrown/);
expect(iThrowError).to.throw(Error, /Error thrown/);
expect(iThrowError).to.throw(new Error('Error thrown'));

而且(同样,来自 chai 的文档),您可以使用以下方法过滤其他错误消息:

expect(iThrowError).to.throw(Error).and.not.throw(/Another Error thrown/);

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2015-06-27
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    相关资源
    最近更新 更多