2015-03-30 50 views
1

我想測試的代碼是:如何構建涉及承諾和第三方NPM模塊的摩卡咖啡單元測試?

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 

這是一箇中間件(我使用快遞)來捕捉各種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

任何幫助將非常感激!

回答

1

調用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() 
2

我只是做:

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

    authentication.hasTokenOrApi mock_req, mock_res, done 

如果done完全沒有叫,測試就會超時。如果它被錯誤調用,那麼Mocha會報告錯誤。

+0

但是不應該在res上存在間諜? – Shamoon 2015-03-31 01:36:35

+0

也許在你的問題中的第二個測試顯示'res'沒有間諜。無論如何,傳遞給'hasTokenOrApi'的回調不是立即調用完成,而是可以在'res'模擬器上執行測試,然後調用'done'。 – Louis 2015-03-31 10:28:13

+0

這並不能解決藍鳥承諾的問題 – Shamoon 2015-04-02 13:24:07