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.

[Node & Testing] Intergration Testing with Node Express的更多相关文章

  1. 前端学习 node 快速入门 系列 —— 报名系统 - [express]

    其他章节请看: 前端学习 node 快速入门 系列 报名系统 - [express] 最简单的报名系统: 只有两个页面 人员信息列表页:展示已报名的人员信息列表.里面有一个报名按钮,点击按钮则会跳转到 ...

  2. node部署静态页面;node上线静态页面

    node部署静态页面上线 静态页面上线可以采用 nginx, tomcat或者node ,我们这里介绍下node部署静态页面 这里采用最简单的上线方式,我们就不用node + express + ej ...

  3. Node学习基础之安装node以及配置环境变量

    第一步去node官网下载nodejs 我放在D盘 接着在cmd输入node -v 就能得到node的版本号 还有npm -v 下来进入安装好的目录 nodejs目录 创建两个文件夹 node_cach ...

  4. Difference Between Performance Testing, Load Testing and Stress Testing

    http://www.softwaretestinghelp.com/what-is-performance-testing-load-testing-stress-testing/ Differen ...

  5. node.js系列笔记之node.js初识《一》

    node.js系列笔记之node.js初识<一> 一:环境说明 1.1 Linux系统CentOS 5.8 1.2 nodejs v0.10.15 1.3 nodejs源码下载地址 htt ...

  6. node.js入门系列(一)--Node.js简介

    什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. 每一种解析器都是一 ...

  7. 【node】使用nvm管理node版本

    写在前面 nvm(nodejs version manager)是nodejs的管理工具,如果你想快速更新node版本,并且不覆盖之前的版本:或者想要在不同的node版本之间进行切换: 使用nvm来安 ...

  8. 什么是Node.js?带你初识Node

    什么是Node.js Nodejs是一个基于Chrome v8引擎的JavaScript运行环境 Node.js使用了一个事件驱动,非阻塞式I/O的模型,使其轻量又高效. Node.js 的包管理器 ...

  9. Node.js的安装以及Node.js的模块管理

    索引: Node.js的安装以及Node.js的模块管理Node.js开发环境搭建以及对ES6的支持Node.js构建Vue.js项目Vue.js单文件组件的开发基于Vue.js的UI组件(Eleme ...

随机推荐

  1. 101.C++继承三种权限

    三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员函数访问 三种继承特点 1.public继承不改变基类成员的访问权限 ...

  2. BZOJ 4430 Guessing Camels

    Description Jaap, Jan, and Thijs are on a trip to the desert after having attended the ACM ICPC Worl ...

  3. JSP中 input type 用法

    JSP中 input type 用法 Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=te ...

  4. JS对象继承与原型链

    1.以复制方式实现的继承 1.1浅拷贝 基本类型的复制 var parent = { lanage: "chinese" } var child = { name: "x ...

  5. js中迭代的常用几种方法

    var arr = [1,3,2,5,3]; //forEach 两个参数,第一个为数组内容,第二个为数组下标arr.forEach(function(item,index) { console.lo ...

  6. CSDN博客给我带来的一些诱惑和选择机会(二):HR“邀请于我”,猎头“有求于我”

    上次,2013年10月8日 ,分享了一篇颇具"正能量"的文章CSDN博客给我带来的一些诱惑和选择机会,获得了很好的正面效果. 10月份,又发生了很多有趣.有意义的事情. 其中,有一 ...

  7. 00075_BigInteger

    1.Java中long型为最大整数类型,对于超过long型的数据如何去表示呢.在Java的世界中,超过long型的整数已经不能被称为整数了,它们被封装成BigInteger对象.在BigInteger ...

  8. Introducing ASLR for FreeBSD

    Shawn WebbOliver Pinter10 July 2014http://www.hardenedbsd.org/ [ 1. Introduction ]Security in FreeBS ...

  9. 洛谷 P1994 有机物燃烧

    P1994 有机物燃烧 题目背景 本来准备弄难点的,还是算了吧 题目描述 输入一种有机物,输出与氧气反应化学方程式中CO2和H2O的系数 输入输出格式 输入格式: 一行,一个字符串,表示有机物 输出格 ...

  10. vim 实际行跟屏幕行移动命令

    我们使用vim的时候,经常会碰到那种情况,就是我们输入的内容过长,中间一直不换行.当我们一行的长度超出电脑屏幕的时候,我们会发现这时候文字自动换行了.不过,如果你使用行号看的话,其实这新的一行是没有行 ...