如何构建涉及 promises 和第三方 NPM 模块的 mocha 单元测试?
How can I structure a mocha unit test that involves promises and third party NPM modules?
我要测试的代码是:
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
任何帮助将不胜感激!
我会这样做:
it.only 'should detect a valid API key', (done) ->
mock_req =
headers:
authorization: 'e16b2ab8d12314bf4efbd6203906ea6c'
authentication.hasTokenOrApi mock_req, mock_res, done
如果根本不调用done
,测试将超时。如果调用出错,那么Mocha会报错。
回调 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()
我要测试的代码是:
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
任何帮助将不胜感激!
我会这样做:
it.only 'should detect a valid API key', (done) ->
mock_req =
headers:
authorization: 'e16b2ab8d12314bf4efbd6203906ea6c'
authentication.hasTokenOrApi mock_req, mock_res, done
如果根本不调用done
,测试将超时。如果调用出错,那么Mocha会报错。
回调 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()