Express 用于身份验证的异步中间件的Jest测试

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

在使用实际的postgres db和一些
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
    性质

  • 我认为ExpressJS很喜欢使用异步函数作为请求处理程序,这样的假设行吗?具体来说,由于
    UserAPI.findUserByCredentials的
    async
    特性,这可以吗

  • Main
    App.js
    findUserById
    使用curried
    UserAPI.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)
      })