使用 Supertest 测试 Express.js 应用

supertest提供了简单易用的客户代理,可以方便地用来测试Express.js应用。 本文介绍如何在Mocha中使用supertest, 以及测试Express应用涉及到的一些问题: 包括如何在每个测试项之前正确地关闭上一个Express Server, 以及如何避免require缓存造成的环境差异。

关于如何使用Mocha测试Node.js代码,请参考利用 Mocha 进行 BDD 风格测试一文。
一个简易的Express应用

先来写一个简单的Express应用,绑定/目录并返回200 harttle。 下文中便来讨论如何正确地测试该应用。

var express = require('express');
var app = express();
app.get('/', function (req, res) {
  res.status(200).send('harttle');
});
var server = app.listen(3000, function () {
  var port = server.address().port;
  console.log('Example app listening at port %s', port);
});
module.exports = server;
Supertest

supertest提供了.get(), .expect()等方法来测试 Express server。 下面给出一个简单的supertest使用示例。

var request = require('supertest');
describe('loading express', function () {
  var server;
  beforeEach(function () {
    server = require('./server');
  });
  afterEach(function () {
    server.close();
  });
  it('responds to /', function testSlash(done) {
    request(server)
      .get('/')
      .expect(200, done);
  });
  it('404 everything else', function testPath(done) {
    request(server)
      .get('/foo/bar')
      .expect(404, done);
  });
});
正确关闭 Express

通常我们希望每项测试都在初始的环境中进行, 于是在每项测试后使用server.close()关闭服务器, 在每项测试前使用server = require('./server')重新开启。 然而server.close()不会立即关闭服务器,这使得测试中常发生EADDRINUSE错误。

但server.close()可以接受一个回调来通知服务器正确关闭事件。 可以利用该回调来使Mocha顺序执行异步过程。只需要将afterEach改为:

afterEach(function (done) {
  server.close(done);
});
清除 require 缓存

尽管我们重启了Expressserver,当require('./server')时Node.js 仍然会返回上次require的缓存。通常的实践中应当用工厂方法来解决, 比如给出makeServer()方法:

function makeServer() {
  var express = require('express');
  var app = express();
  app.get('/', function (req, res) {
    res.status(200).send('harttle');
  });
  var server = app.listen(3000, function () {
    var port = server.address().port;
    console.log('Example app listening at port %s', port);
  });
  return server;
}
module.exports = makeServer;
这样每次调用makeServer()都会重新执行上述代码。 然而为了写测试去更改代码结构有时并不可行,正确的方式是通过Node.js API来清除缓存:

beforeEach(function () {
  delete require.cache[require.resolve('./server')];
  server = require('./server');
});
其实有一个NPM库really-need已经封装了上述代码,导入该工具即可覆盖require的默认行为。

require = require('really-need');
beforeEach(function () {
  server = require('./server', { bustCache: true });
});
最终代码

最终的测试代码如下:

var request = require('supertest');
require = require('really-need');
describe('loading express', function () {
  var server;
  beforeEach(function () {
    server = require('./server', { bustCache: true });
  });
  afterEach(function (done) {
    server.close(done);
  });
  it('responds to /', function testSlash(done) {
    request(server)
      .get('/')
      .expect(200, done);
  });
  it('404 everything else', function testPath(done) {
    console.log('test 404')
    request(server)
      .get('/foo/bar')
      .expect(404, done);
  });
});

时间: 2024-09-14 05:55:21

使用 Supertest 测试 Express.js 应用的相关文章

通过 Node.js, Express.js 实现 HTTP/2 Server Push

什么是 HTTP/2 Server Push HTTP/2 是 Web 开发的新标准,拥有很多不错的优点能够让 Web 访问更快且开发的工作更轻松简单.比如,引入多路复用传输不用合并资源,服务器推送(Server Push)资源让浏览器预加载. 该文不会讲述 HTTP/2 的所有优势.你可以通过上篇文章了解更多{% post_link http2-node-express %}.该文主要关注于在 Node.js环境使用 Express.js 和 HTTP/2 库 spdy. 服务器推送(Serv

Express.JS使用详解_node.js

安装了node(下载)之后, 在你的机器上创建一个目录,开始你的第一个应用程序. $ mkdir hello-world 在这个目录中你将定义应用程序"包",这和任何其他node的包没有什么不同.文件目录中的json文件,明确定义了一个依赖项.你可以用npm命令获取express最新版本,你喜欢这样做,而不是安装"3.x"以外的版本,以防止任何未知的惊喜. { "name": "hello-world", "desc

EXPRESS.JS再出发

那个那个MEAN的书,看得七七八八,有了大概,现在就要一样一样的加深记忆啦.. EXPRSS.JS的东东,网上有现成入门书籍:   第一期代码测试:   var express = require('express'); var app = express(); var handlebars = require('express3-handlebars') .create({defaultLayout: 'main'}); app.engine('handlebars', handlebars.

Express.js 作者弃用 Node.js,转向 Go 语言

今天 Express 的作者 TJ Holowaychuk 发了一篇文章,正式宣告和 Node.js 拜拜了,转向 Go 语言. Go verses Node 如果你在做分布式工作,你会发现 Go 语言丰富的并发原语非常有帮助.虽然我们用 Node 的 generator 也可以做类似的事,但在我看来,generator 永远只能做一半.没有独立的栈错误处理和报告,充其量是中等.我也不想再等(Node)社区花3 年去整理(改善),尤其是我们已经有了可用并不错的解决方案. 在我看来,Go 语言的错

使用Jasmine和Karma对AngularJS页面程序进行测试_node.js

AngularJS是继jQuery之后发生在JavaScript上最好的东西.这也是JavaScript开发一直以来想要的方式.Angular主要的优点之一就是它的依赖注入(Dependency Injection),它非常利于代码的单元测试.但有点小怪异的是,我在无论如何都没能找到一个介绍如何做单元测试的教程. 当然有很多不错的推荐:使用Jasmine测试框架和Karma测试执行器(Test Runner):但是并没有一篇完整的从无到有指导如何测试的教程.所以我写了这篇文章.我在网上找了很多资

测试多种js在一个页面的兼容性

<!DOCTYPE html> <html lang="en"> <head> <title>testAll</title> <link href="css/bootstrap.min.css" rel="stylesheet" /> <link href="css/prettyCheckable.css" rel="stylesheet&

JS测试与接入CI指南

js代码自动化的测试有什么好处? 1.开发者在写测试脚本的时候,能够更好的理解代码的的功能,返回值等等. 2.能够实现准确直接的测试,并立即看到测试结果,进行调整. 3.面对复杂的项目,对代码的修改有可能会牵一发动全身,代码的改动可能会影响到其他部分的功能,自动化测试能帮我们整体检查一遍. 4.测试的结果能够当做一个代码质量的依据. 在segmentfault上搜索"探知js测试",可以得到三篇系列文章对js测试进行讲解,第一篇的地址:https://segmentfault.com/

nodejs教程 安装express及配置app.js文件的详细步骤_json

安装express.js 如果你安装了npm,安装变得很简单,只需要在终端中运行下面的代码即可: 复制代码 代码如下: npm install express -gd -g代表安装到NODE_PATH的lib里面,而-d代表把相依性套件也一起安装.如果沒有-g的话会安装目前所在的目录(会建立一个node_modules的文件夹),你可以透过以下指令来比较两者的不同: 复制代码 代码如下: npm list -gnpm list 如果没有npm,那么我可以使用github来git下来最新的expr

js/bat批处理调用谷歌浏览器chrome批量打开网页测试web性能

批处理批量打开网页 其实用java就可以搞定,但是这么一个轻巧的测试,js或者bat批处理去一次性打开几百个网页测试一下页面没必要上java 两者的区别,js的话,只能打开多个浏览器实例,不方便查看效果.bat的话,是一个浏览器里面N个标签页,比较爽一些.   js版:test.html < html > <head > <title > 测试 < /title> <script> function iopen(){ for(var i=0;i&