Express 用于身份验证的异步中间件的Jest测试
在使用实际的postgres db和一些Express 用于身份验证的异步中间件的Jest测试,express,async-await,jestjs,currying,Express,Async Await,Jestjs,Currying,在使用实际的postgres db和一些fetch()-ing代码进行重构之前,我使用一个静态数组构建一个用户表。目前,测试工作正常,但显然它们是同步工作的。以下是占位符API代码: // UserAPI.js let findUserById = (credentials = {}) => { const { userId } = credentials if (userId) { const foundUser = users.find(user => user
fetch()
-ing代码进行重构之前,我使用一个静态数组构建一个用户表。目前,测试工作正常,但显然它们是同步工作的。以下是占位符API代码:
// UserAPI.js
let findUserById = (credentials = {}) => {
const { userId } = credentials
if (userId) {
const foundUser = users.find(user => user.id === userId)
if (foundUser !== undefined) {
const { password: storedpassword, ...user } = foundUser
return user
}
}
return null
}
exports.byId = findUserById
下面是一个示例测试:
// excerpt from TokenAuth.test.js
const UserAPI = require('../lib/UserAPI')
describe('With TokenAuth middleware', () => {
beforeEach(() => {
setStatus(0)
})
it('should add user to req on authorised requests', () => {
const token = createToken(fakeUser)
const authReq = { headers: { authorization: 'Bearer ' + token } }
const myMiddleware = TokenAuth(UserAPI.byId)
myMiddleware(authReq, fakeRes, fakeNext)
// expect(authReq.user).toStrictEqual({ id: 1, username: 'smith@example.com' });
expect(authReq.user.username).toStrictEqual('smith@example.com')
expect(authReq.user.id).toStrictEqual(1)
})
})
这运行良好,并且与其他测试一起提供了我想要的覆盖率。但是,我现在想检查测试是否将处理async/await
性质的fetch()
代码,我将用于正确的UserAPI.js
文件。因此,我将占位符代码重新编写为:
// UserAPI.js with added async/await pauses ;-)
let findUserById = async (credentials = {}) => {
const { userId } = credentials
// simulate url resolution
await new Promise(resolve => setTimeout(() => resolve(), 100)) // avoid jest open handle error
if (userId) {
const foundUser = users.find(user => user.id === userId)
if (foundUser !== undefined) {
const { password: storedpassword, ...user } = foundUser
return user
}
}
return null
}
exports.byId = findUserById
。。。在这一点上,我开始得到一些可爱的失败,因为我认为这是返回未解决的承诺
我的问题有两方面:
UserAPI.test.js
测试来处理findUserByCredentials()
的新的async
性质UserAPI.findUserByCredentials的async
特性,这可以吗
App.js
对findUserById
使用curriedUserAPI.byId()
// App.js (massively simplified)
const express = require('express')
const TokenAuth = require('./middleware/TokenAuth')
const RequireAuth = require('./middleware/RequireAuth')
const UserAPI = require('./lib/UserAPI')
let router = express.Router()
const app = express()
app.use(TokenAuth(UserAPI.byId))
app.use(RequireAuth)
app.use('/users', UserRouter)
module.exports = app
我的TokenAuth中间件现在将沿着以下路线运行:
// TokenAuth.js (simplified)
const jwt = require('jsonwebtoken')
require('dotenv').config()
const signature = process.env.SIGNATURE
let TokenAuth = findUserById => async (req, res, next) => {
let header = req.headers.authorization || ''
let [type, token] = header.split(' ')
if (type === 'Bearer') {
let payload
try {
payload = jwt.verify(token, signature)
} catch (err) {
res.sendStatus(401)
return
}
let user = await findUserById(payload)
if (user) {
req.user = user
} else {
res.sendStatus(401)
return
}
}
next()
}
module.exports = TokenAuth
一个部分答案是,我们只需在
中间件
调用中添加一个async/await:
it('should add user to req on authorised requests', async () => {
const token = createToken(fakeUser)
const authReq = { headers: { authorization: 'Bearer ' + token } }
const myMiddleware = TokenAuth(UserAPI.byId)
await myMiddleware(authReq, fakeRes, fakeNext)
// expect(authReq.user).toStrictEqual({ id: 1, username: 'smith@example.com' });
expect(authReq.user.username).toStrictEqual('smith@example.com')
expect(authReq.user.id).toStrictEqual(1)
})