简体   繁体   中英

When testing NodeJS code with Mocha and Chai assertions, how can I expect an exception to be thrown from a callback?

I'm using Mocha with Chai expect assertions to test my NodeJS app. I can write a test like this and it works just fine:

describe 'My Code', ->
    it 'should handle exceptions', (done) ->
        fn = ->
            # Do something that causes an error
            throw new Error()
        expect(fn).to.throw(Error)
        done()

But what if fn has to first call a function that takes a callback, and might throw an error based on the result? For example, if it hits the database and might throw an exception based on the result? This doesn't work:

describe 'My Callback-using Code', ->
    it 'should handle exceptions thrown from callbacks', ->

        doSomethingAsync = (callback) ->
            setTimeout (->
                callback(somecalculatedvalue)
            ), 1000


        fn = ->
            doSomethingAsync (value) ->
                # The value meets a condition so throw an error
                throw new Error()

        expect(fn).to.throw(Error)
        done()

The test ends when done is called, but the exception hasn't yet been thrown and so the test fails. How can I make this test pass?

EDIT: As per Peter's answer, this is not the right approach. This could be better expressed in a style similar to this:

describe 'My Error Handling Code', ->
    it 'should handle errors', ->

        fn = (callback) ->
            getValueFromDatabase (value) ->
                if value.isBad()
                    callback({ error: 'The value is bad.'})
                else
                    callback()

        fn (e) ->
            expect(e).to.exist()
            done()

Thanks everyone for your help! This will help in a lot of the things I'm working on.

Is this your own code or a library you are using? Throwing an exception after an async operation is a no-no in node. You must pass an error as the first argument to a callback function. The stack has been reset so there's no way to catch an exception thrown. Throwing exceptions only works for synchronous code and thus you almost never see it in node code because async code is constantly starting new stacks without calling code available to catch exceptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM