zoukankan      html  css  js  c++  java
  • [Node & Testing] Intergration Testing with Node Express

    We have express app:

    import _ from 'lodash'
    import faker from 'faker'
    import express from 'express'
    import bodyParser from 'body-parser'
    import getTokenFromHeader from '../../src/routes/utils/get-token-from-header'
    
    export default startServer
    
    const users = _.times(20, () => faker.helpers.contextualCard())
    const userAuth = {
      username: 'jane',
      password: 'I have a secure password',
    }
    const user = {
      token: 'Wanna-hear-a-secret?-I-sometimes-sing-in-the-shower!',
    }
    
    function startServer() {
      const app = express()
    
      app.use(bodyParser.json())
    
      function auth(req, res, next) {
        const token = getTokenFromHeader(req)
        if (!token || token !== user.token) {
          res.sendStatus(401)
        } else {
          next()
        }
      }
    
      const userRouter = express.Router()
      userRouter.get('/', (req, res) => {
        const {query: {limit = 20, offset = 0}} = req
        res.json({users: _.take(users.slice(offset), limit)})
      })
    
      // Preload user objects on routes with ':username'
      userRouter.param('username', (req, res, next, param) => {
        req.user = users.find(({username}) => username === param)
        next()
      })
    
      userRouter.get('/:username', (req, res) => {
        if (req.user) {
          res.json({user: req.user})
        } else {
          res.sendStatus(404)
        }
      })
    
      userRouter.post('/', auth, (req, res) => {
        users.unshift(req.body.user)
        res.json({user: users[0]})
      })
    
      userRouter.delete('/:username', auth, (req, res) => {
        users.splice(users.indexOf(req.user), 1)
        res.json({success: true})
      })
    
      const authRouter = express.Router()
      authRouter.post('/', (req, res) => {
        if (
          req.body.username === userAuth.username &&
          req.body.password === userAuth.password
        ) {
          res.json({user})
        } else {
          res.sendStatus(401)
        }
      })
    
      const apiRouter = express.Router()
      apiRouter.use('/users', userRouter)
      apiRouter.use('/auth', authRouter)
    
      app.use('/api', apiRouter)
    
      return new Promise(resolve => {
        const server = app.listen(3001, () => {
          resolve(server)
        })
      })
    }

    As you can see, we wrap Express App into a function 'startServer' and export it as default export. The return value of this function is the server which wrap into a Promise.

    The good part for doing this way is that we can start and stop server whenever we want to prevent menory leak or "ADDRESS IN USED" problem.

    import startServer from '../start-server'
    import axios from 'axios'
    
    let server
    
    beforeAll(async () => {
        server = await startServer()
    })
    
    afterAll(done => server.close(done))
    
    test('can get users', async () => {
        const user = await axios
            .get('http://localhost:3001/api/users')
            .then(response => response.data.users[0])
    
        // toMatchObject, to check whether user object
        // has 'name' prop which is a string
        // and 'username' prop which is a string
        // this is a subset, doesn't need to match all the object props
        expect(user).toMatchObject({
            name: expect.any(String),
            username: expect.any(String)
        })
    })
    
    // Test offset and limit should work
    // first get 5 users
    // then get last two users by given limit and offset
    // then check tow users and equal to last tow user in five users.
    test('get users, limit and offset should work', async () => {
        const fiveUsersPromise = axios
            .get('http://localhost:3001/api/users?limit=5')
            .then(response => response.data.users)
        const twoUsersPromise = axios
            .get('http://localhost:3001/api/users?limit=2&offset=3')
            .then(response => response.data.users)
    
        const response = await Promise
            .all([fiveUsersPromise, twoUsersPromise])
        const [fiveUsers, twoUsers] = response
        const [, , ,firstFiveUser, secondFiveUser] = fiveUsers
        const [firstTwoUser, secondTwoUser] = twoUsers
        expect(firstTwoUser).toEqual(firstFiveUser)
        expect(secondFiveUser).toEqual(secondTwoUser)
    })

    In the test, we call 'beforeAll' to start the server and 'afterAll' to close the server.

  • 相关阅读:
    Neptune w800开发版ubuntu linux环境编译通过——如何搭建开发环境
    neptune HarmonyOS开发板视频教程-环境搭建-编译-烧录-外设控制
    Neptune开发板与hiSpark开发板底板的管脚不兼容
    《设计心理学》要点(上)
    NLP(三十二):大规模向量相似度检索方案
    VIM编辑器设置
    (十一)pytorch加速训练的17种方法
    (十)pytorch多线程训练,DataLoader的num_works参数设置
    NLP(三十一):用transformers库的BertForSequenceClassification实现文本分类
    NLP(三十):BertForSequenceClassification:Kaggle的bert文本分类,基于transformers的BERT分类
  • 原文地址:https://www.cnblogs.com/Answer1215/p/7554662.html
Copyright © 2011-2022 走看看