assert.throws on asynchronous method

2019-09-06 00:02发布

I am having troubles trying to use assert.throws in my Mocha unit tests,

I have this method:

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
  })
}

And in my unit tests I have:

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

The results I get are random, sometimes the error is being thrown (I got Uncaught Error: something went wrong) and the test is failing, sometimes it passes.

I have tried a couple of other things, such as passing the error through the callback and do:

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

And I got as output: AssertionError: Missing expected exception (Error).. so I guess he doesn't see anything...

The only way I can get assert.throws to work as I expected is with a synchronous function:

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

I was wondering if it had to do something with done(), but still even by calling it in my callback, no success. Did I miss something?

2条回答
Summer. ? 凉城
2楼-- · 2019-09-06 00:14

This is the correct code

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

The message

AssertionError: Missing expected exception (Error)..

says that the wrong type of exception was thrown. You don't say which assert you are using, but presumably the 'Error' in the assert.throws specifies what type of exception is expected. You need to change it to match the actual exception that is thrown.

I suppose it is also possible that the message is saying that no exception was actually thrown. You'll need to check the documentation for your library or write a simple test to check what is wrong.

查看更多
姐就是有狂的资本
3楼-- · 2019-09-06 00:18

I managed to get it to work by improving David Norman's answer. As I stated in my question, my test lacked the done() call, but even if I was calling it after the throw err, I was having a timeout exception with Mocha. Anyway, this is the code snippet I used for the test of another asynchronous method I wrote, and it pass and does not get a timeout error:

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/ matches the text description of the Error being thrown in fn's callback. It could be Error but I wanted to be sure of wich error assert.throws was detecting.

查看更多
登录 后发表回答