2

我正在使用 Mocha 和 Chai 期望断言来测试我的 NodeJS 应用程序。我可以写一个这样的测试,它工作得很好:

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

但是如果fn必须首先调用一个接受回调的函数,并且可能会根据结果抛出一个错误呢?例如,如果它命中数据库并可能根据结果抛出异常?这不起作用:

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

调用 done 时测试结束,但尚未引发异常,因此测试失败。我怎样才能使这个测试通过?

编辑:根据彼得的回答,这不是正确的方法。这可以用类似于以下的样式更好地表达:

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

感谢大家的帮助!这将有助于我正在做的很多事情。

4

1 回答 1

7

这是您自己的代码还是您正在使用的库?在异步操作后抛出异常是节点中的禁忌。您必须将错误作为第一个参数传递给回调函数。堆栈已被重置,因此无法捕获抛出的异常。抛出异常仅适用于同步代码,因此您几乎不会在节点代码中看到它,因为异步代码不断启动新堆栈,而无需调用可用于捕获异常的代码。

于 2014-01-30T23:26:58.517 回答