【问题标题】:How can I structure a mocha unit test that involves promises and third party NPM modules?如何构建一个涉及 Promise 和第三方 NPM 模块的 mocha 单元测试?
【发布时间】:2015-06-03 21:01:50
【问题描述】:

我要测试的代码是:

exports.hasTokenOrApi = (req, res, next) ->
  if not req.headers?.authorization
    return res.status(403).end()

  new Promise (resolve, reject) ->
    if req.headers.authorization.length is 32
      # We are using an API key
      global.db.User.find
        where:
          api_key: req.headers.authorization
      .then (dbUser) ->
        resolve dbUser.apiDisplay()
    else
      # We are using a redis session
      req.redisSession.getAsync
        app: 'sessions'
        token: req.headers.authorization
      .then (response) ->
        resolve response.d
  .then (user) ->
    if not user.id
      return res.status(403).end()
    req.user = user

    next()
  .catch (err) ->
    next err

这是一个中间件(我使用 Express),用于捕获各种 API 端点的令牌或 API 密钥。

到目前为止,我的测试是:

describe 'Authentication Middleware', ->
  mock_res = {}
  before (done) ->
    mock_res =
      status: ->
        @
      end: ->
        @

    global.db =
      User:
        find: ->
          @
        then: ->
          id: 1


    done()

  it 'should return a 403 is no authorization is set in the header', ->
    mock_req = {}
    mock_next = null

    status_spy = sinon.spy mock_res, 'status'
    end_spy = sinon.spy mock_res, 'end'

    authentication.hasTokenOrApi mock_req, mock_res, mock_next
    status_spy.calledWith(403).should.equal true
    end_spy.called.should.equal true

  it.only 'should detect a valid API key', ->
    mock_req =
      headers:
        authorization: 'e16b2ab8d12314bf4efbd6203906ea6c'
    mock_next = sinon.spy()

    authentication.hasTokenOrApi mock_req, mock_res, mock_next
    mock_next.called.should.equal true

第一次测试很好,效果很好,解决了我所有的问题。 第二个工作不正常。我认为这与承诺有关?我的测试我们返回false,而我想做的是true

任何帮助将不胜感激!

【问题讨论】:

    标签: unit-testing coffeescript promise mocha.js sinon


    【解决方案1】:

    我会这样做:

    it.only 'should detect a valid API key', (done) ->
        mock_req =
          headers:
            authorization: 'e16b2ab8d12314bf4efbd6203906ea6c'
    
        authentication.hasTokenOrApi mock_req, mock_res, done
    

    如果根本没有调用done,测试将超时。如果调用有错误,则 Mocha 会报错。

    【讨论】:

    • 但是资源上不应该有间谍吗?
    • 可能,但您问题中的第二个测试显示res 没有间谍。无论如何,传递给hasTokenOrApi 的回调可以在res 模拟上执行测试,然后调用done,而不是立即调用。
    【解决方案2】:

    回调next 将被异步调用。您的测试在有机会被调用之前检查mock_next.called。您可以通过在以下位置编写自己的回调来验证是否调用了 next 回调:

    authentication.hasTokenOrApi mock_req, mock_res, err ->
        if err
            done err
        # if the code has entered this callback, and there's no error 
        # that means that the promise has resolved and everything's good... 
        # we can end the test now
        done()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-22
      相关资源
      最近更新 更多