4

我在 Mocha 单元测试中尝试使用 assert.throws 时遇到了麻烦,

我有这个方法:

var getMetadatas = function (file, callback) {
  fs.readFile(file, {encoding: 'utf-8'}, function(err, data){
    // stuff
      if (somethingWentWrong) 
        throw new Error('Something went wrong')
    // callback call
  })
}

在我的单元测试中,我有:

it('should throw an error when passing a bad formatted file', function(){ 
  assert.throws(
    getMetadatas('someBadFormattedFile', function(metadatas){})
  )
})

我得到的结果是随机的,有时会抛出错误(我得到了Uncaught Error: something went wrong)并且测试失败,有时它会通过。

我尝试了其他一些事情,例如通过回调传递错误并执行以下操作:

var fn = function(){ 
  parse.getMetadatas('test/test_incorrect.md', function (err, metas) {
      if (err) throw err
  })
}
assert.throws( function() { fn() }, Error )

我得到了输出:AssertionError: Missing expected exception (Error)..所以我猜他什么也没看到......

我可以assert.throws按预期工作的唯一方法是使用同步函数:

assert.throws(
  function () {throw new Error('error')}
)

我想知道它是否必须与 做某事done(),但即使在我的回调中调用它,也没有成功。我错过了什么?

4

3 回答 3

3

如果我们删除注释,这一切都非常简单,只需 3-4 行代码。您只需要遵循我在下面介绍的特定模式即可。

it('Should throw error from an asynchronous function', async function() {
   
    try {
        await someAsycnFunction();

        /**
         * The next line forces the test fail in case someAsyncFucntion() does not throw.
         */
        assert.fail('The expected Error was not thrown.');

    } catch (err) {

        /**
         * (optional) Here we assert the error object prototype name for the cases when we
         * want to check the error type is the expected one (e.g. we have
         * extended the base JS exception to make our own exception).
         */
        assert.typeOf(err, 'Error', 'someAsycnFunction did not throw expected error.');

        /**
         * (optional) Here we assert that the error message is the expected one.
         */
        assert.include(err.message, 'ExpectedErrorMessage', 'someAsycnFunction error message does not match the expected one.');

        /**
         * (optional) Here we re-throw the caught error to assert it includes the
         * expected error message substring (as a regex). 
         */
        assert.throws(() => {
            throw err;
        }, Error, /ExpectedErrorMessage/);
    }

});

最基本的实现可能只包括您在catch块中选择的一个断言。这种方法的关键是将抛出的异步函数包装在块中try/catch并强制使测试失败try

于 2020-07-05T11:28:35.503 回答
2

这是正确的代码

var fn = function(){ 
  parse.getMetadatas('test/test_incorrect.md', function (err, metas) {
      if (err) throw err
  })
}
assert.throws( function() { fn() }, Error )

讯息

AssertionError: Missing expected exception (Error)..

表示抛出了错误类型的异常。您没有说您正在使用哪个断言,但大概 assert.throws 中的“错误”指定了预期的异常类型。您需要更改它以匹配引发的实际异常。

我想也有可能消息是说实际上没有抛出异常。您需要检查您的库的文档或编写一个简单的测试来检查问题所在。

于 2013-10-09T03:00:16.183 回答
0

我设法通过改进大卫诺曼的回答来让它发挥作用。正如我在问题中所说,我的测试缺少done()调用,但即使我在 之后调用它throw err,我也会遇到 Mocha 超时异常。无论如何,这是我用于测试我编写的另一个异步方法的代码片段,它通过并且没有出现超时错误:

var fn = function () {
  fs.rmrf(path.join(pathDir, 'non', 'existing'), function (err) {
    done()
    assert.ifError(err)
  })
}
assert.throws(function () { fn() } , /No directory/)

Where匹配在的回调/No directory/中抛出的错误的文本描述。fn可能是Error,但我想确定assert.throws检测到的错误。

于 2013-10-15T10:30:36.900 回答