猫鼬承诺在某些条件下不解决

时间:2014-06-17 12:51:28

标签: javascript coffeescript mongoose promise mocha

我有以下代码,我正在尝试编写使用mocha的单元测试。在某些情况下,这是按预期工作的,但在其他情况下,承诺似乎永远不会解决。你能帮我解决一下吗?

正在测试的代码:

exports.inGroup = (group, user) ->
    return user.groups.indexOf(group) >= 0

##
# A promise returning function that returns the list
# of viewable channels for a user.
##
exports.getUserViewableChannels = (user) ->

    # if admin allow all channels
    if exports.inGroup 'admin', user
        return Channel.find({}).exec()
    else        
        # otherwise figure out what this user can view
        return Channel.find({ txViewAcl: { $in: user.groups } }).exec()

现在,当我测试非管理员用户时,这可以正常工作:

user = new User
    firstname: 'Some'
    surname: 'User'
    email: 'some@user.net'
    groups: [ 'HISP' , 'group2' ]

it "should return channels that a user can view", (done) ->
    promise = authorisation.getUserViewableChannels user
    promise.then (channels) ->
        channels.should.have.length(2)
        done()
    , (err) ->
        done err

但是,当我测试管理员用户时,承诺无法解决:

user3 = new User
    firstname: 'Random'
    surname: 'User'
    email: 'someguy@meh.net'
    groups: [ 'admin' ]

it "should return all channels for viewing if a user is in the admin group", (done) ->
    promise = authorisation.getUserViewableChannels user3
    promise.then (channels) ->
        channels.should.have.length(3)
        done()
    , (err) ->
        done err

在这种情况下,mocha测试超时:

Error: timeout of 2000ms exceeded

1 个答案:

答案 0 :(得分:3)

嗯,这很脏,但是 - 如果断言channels.should.have.length(2)失败,就会发生坏事。您在上没有.catch处理程序断言,这意味着承诺将被拒绝。

由于mpromise(Mongoose promises)没有任何好的未处理拒绝检测,这将导致承诺的无声失败,并且由于在这种情况下永远不会调用done,因此Mocha不知道该怎么做。我强烈建议使用Bluebird而不是Mongoose的承诺,因为它们都更快(是的,即使使用Mongoose)也不会让沉默失败发生,并且会为你追踪它们。

以下,使用Mocha在最新版本中提供的较新的promise语法,应该可以使用。

it "should return all channels for viewing if a user is in the admin group", () ->
    promise = authorisation.getUserViewableChannels user3
    promise.then (channels) ->
      channels.should.have.length(3)