目录
  1. 简介
  2. 准备开始
  3. Restful API测试实战
      Example 1 - GET
      Example 2 - Post
      Example 3 - Put
      Example 4 - Delete
  4. Troubleshooting
  5. 参考文档

简介

经过上一篇文章的介绍,相信你已经对mocha, chai有一定的了解了, 本篇主要讲述如何用supertest来测试nodejs项目中的Restful API, 项目基于express框架。

SuperTest 是 SuperAgent一个扩展, 一个轻量级 HTTP AJAX 请求库.

SuperTest provides high-level abstractions for testing node.js API endpoint responses with easy to understand assertions.

准备开始

npm安装命令

npm install supertest

nodejs项目文件目录结构如下

├── config
│ └── config.json
├── controllers
│ └── dashboard
│ └── widgets
│ └── index.js
├── models
│ └── widgets.js
├── lib
│ └── jdbc.js
├── package.json
└── test
└── controllers
└── dashboard
└── widgets
└── index_IntegrationTest.js

测试代码写在index_IntegrationTest.js这个文件中

Restful API测试实战

测试依赖库

var express = require('express');
var kraken = require('kraken-js');
var request = require('supertest');
var chai = require('chai');
var assert = chai.assert;

##转载注明出处:http://www.cnblogs.com/wade-xu/p/4673460.html

Example 1 - GET

Controller/dashboard/widgets/index.js

var _widgets = require('../../../models/widgets.js');

module.exports = function(router) {

  router.get('/', function(req, res) {
_widgets.getWidgets(req.user.id)
.then(function(widgets){
return res.json(widgets);
})
.catch(function(err){
return res.json ({
code: '000-0001',
message: 'failed to get widgets:'+err
});
});
});
};

测试代码:

var kraken = require('kraken-js');
var express = require('express');
var request = require('supertest');
var aweb = require('acxiom-web');
var chance = new(require('chance'))();
var chai = require('chai');
var assert = chai.assert; describe('/dashboard/widgets', function() { var app, mock; before(function(done) {
app = express();
app.on('start', done); app.use(kraken({
basedir: process.cwd(),
onconfig: function(config, next) {
//some config info next(null, config);
}
})); mock = app.listen(1337); }); after(function(done) {
mock.close(done);
}); it('get widgets', function(done) {
request(mock)
.get('/dashboard/widgets/')
.set('Accept', 'application/json')
.expect(200)
.expect('Content-Type', 'application/json; charset=utf-8')
.end(function(err, res) {
if (err) return done(err);
assert.isArray(res.body, 'return widgets object');
done();
});
}); });

Example 2 - Post

被测代码:

  router.post('/', function(req, res) {
_widgets.addWidget(req.user.id, req.body.widget)
.then(function(widget){
return res.json(widget);
})
.catch(function(err){
return res.json ({
code: '000-0002',
message: 'failed to add widget:' + err
});
});
});

测试代码:

  it('add widgets', function(done) {
var body = {
widget: {
type: 'billing',
color: 'blue',
location: {
x: '1',
y: '5'
}
}
}; request(mock)
.post('/dashboard/widgets/')
.send(body)
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
if (err) return done(err);
assert.equal(res.body.type, 'billing');
assert.equal(res.body.color, 'blue');
done();
});
});

##转载注明出处:http://www.cnblogs.com/wade-xu/p/4673460.html

Example 3 - Put

被测代码

  router.put('/color/:id', function(req, res) {
_widgets.changeWidgetColor(req.params.id, req.body.color)
.then(function(status){
return res.json(status);
})
.catch(function(err){
return res.json ({
code: '000-0004',
message: 'failed to change widget color:' + err
});
});
});

测试代码

  describe('change widget color', function() {
var id = '';
before(function(done) {
var body = {
widget: {
type: 'billing',
color: 'blue',
location: {
x: '1',
y: '5'
}
}
}; request(mock)
.post('/dashboard/widgets/')
.send(body)
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
if (err) return done(err);
id = res.body.id;
done();
}); }); it('change widget color to white', function(done) {
var body = {
color: 'white'
}; request(mock)
.put('/dashboard/widgets/color/' + id)
.send(body)
.expect(200)
.expect({
status: 'success'
})
.expect('Content-Type', /json/)
.end(function(err, res) {
if (err) return done(err);
done();
});
});
});

在这个测试case中,前提是要先create 一个widget, 拿到id之后你才可以针对这个刚创建的widget修改, 所以在it之前用了 before 做数据准备。

Example 4 - Delete

被测代码

  router.delete('/:id', function(req, res) {
_widgets.deleteWidget(req.user.id, req.params.id)
.then(function(status){
return res.json(status);
})
.catch(function(err){
return res.json ({
code: '000-0003',
message: 'failed to delete widget:' + err
});
});
});

测试代码

  describe('delete widget', function() {
var id = '';
before(function(done) {
var body = {
widget: {
type: 'billing',
color: 'blue',
location: {
x: '1',
y: '5'
}
}
}; request(mock)
.post('/dashboard/widgets/')
.send(body)
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
if (err) return done(err);
id = res.body.id;
done();
}); }); it('delete a specific widget', function(done) {
request(mock)
.del('/dashboard/widgets/' + id)
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
if (err) return done(err);
assert.deepEqual(res.body, {
status: 'success'
});
done();
});
});
});

注意这里用的是del 不是 delete, Supertest提供的delete方法是del, 不是delete

##转载注明出处:http://www.cnblogs.com/wade-xu/p/4673460.html

测试结果如下:

Troubleshooting

1. 当你用request().delete() 时报错TypeError: undefined is not a function

换成request().del()

参考文档

Mocha: http://mochajs.org/

Chai: http://chaijs.com/

SuperTest: https://www.npmjs.com/package/supertest

感谢阅读,如果您觉得本文的内容对您的学习有所帮助,您可以点击右下方的推荐按钮,您的鼓励是我创作的动力。

##转载注明出处:http://www.cnblogs.com/wade-xu/p/4673460.html

带你入门带你飞Ⅱ 使用Mocha + Chai + SuperTest测试Restful API in node.js的更多相关文章

  1. 使用 TypeScript & mocha & chai 写测试代码实战(17 个视频)

    使用 TypeScript & mocha & chai 写测试代码实战(17 个视频) 使用 TypeScript & mocha & chai 写测试代码实战 #1 ...

  2. 带你入门带你飞Ⅰ 使用Mocha + Chai + Sinon单元测试Node.js

    目录 1. 简介 2. 前提条件 3. Mocha入门 4. Mocha实战 被测代码 Example 1 Example 2 Example 3 5. Troubleshooting 6. 参考文档 ...

  3. #单元测试#以karma+mocha+chai 为测试框架的Vue webpack项目(二)

    学习对vue组件进行单元测试,先参照官网编写组件和测试脚本. 1.简单的组件 组件无依赖,无props 对于无需导入任何依赖,也没有props的,直接编写测试案例即可. /src/testSrc/si ...

  4. #单元测试#以karma+mocha+chai 为测试框架的Vue webpack项目(一)

    目标: 为已有的vue项目搭建 karma+mocha+chai 测试框架 编写组件测试脚本 测试运行通过 抽出共通 一.初始化项目 新建项目文件夹并克隆要测试的已有项目 webAdmin-web 转 ...

  5. node.js入门基础

    内容: 1.node.js介绍 2.node.js内置常用模块 3.node.js数据交互 一.node.js介绍 (1)node.js特点 与其他语言相比,有以下优点: 对象.语法和JavaScri ...

  6. 极简 Node.js 入门 - Node.js 是什么、性能有优势?

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  7. DTSE Tech Talk | 第10期:云会议带你入门音视频世界

    摘要:本期直播主题是<云会议带你入门音视频世界>,华为云媒体服务产品部资深专家金云飞,与开发者们交流华为云会议在实时音视频行业中的集成应用,帮助开发者更好的理解华为云会议及其开放能力. 本 ...

  8. 可能是史上最强大的js图表库——ECharts带你入门

    PS:之前的那篇博客Highcharts——让你的网页上图表画的飞起 ,评论中,花儿笑弯了腰 和 StanZhai 两位仁兄让我试试 ECharts ,去主页看到<Why ECharts ?&g ...

  9. 史上最强大的js图表库——ECharts带你入门(转)

    出处:http://www.cnblogs.com/zrtqsk/p/4019412.html PS:之前的那篇博客Highcharts——让你的网页上图表画的飞起 ,评论中,花儿笑弯了腰 和 Sta ...

随机推荐

  1. 2016年5月面试题(Unity&iOS)

    NGUI的DrawCall drawcall定义:对底层图形程序(比如:OpenGL ES)接口的调用,以在屏幕上画出东西. List在内存中连续的空间保存 List是线性直接存储类型 mipMap是 ...

  2. Android之自定义控件-城市选择

    实现效果: 图片素材:           --> 首先, 城市数据字节放在 Json 文件, 就不网络获取了. city.json 存放 Json 数据: { "result&quo ...

  3. (整理) Json语法规则

    { "staff":[ {"name":"haha1", "age":20}, {"name":&q ...

  4. SQL server2008-对象资源管理器

    对象资源管理器:数据库 .安全性.服务器对象.复制.管理 .SQL server代理 六部分组成

  5. 上传到github!

    今天课上在冯老师的带领下终于在github上成功上传了东西但是还有很多没用的东西,慢慢研究改进! https://github.com/Hxy94264/GitHubTest https://gith ...

  6. Linux删除apt-get安装的软件

    我们都知道安装软件最简单的方法是apt-get install,但是卸载就不常用了,如何卸载呢?1.sudo apt-get remove xxxxxsudo apt-get autoremove2. ...

  7. 转载《Android-TabHost 选项卡功能用法详解》

    一. TabHost介绍 TabHost组件可以在界面中存放多个选项卡, 很多软件都使用了改组件进行设计; 1. TabHost常用组件 TabWidget : 该组件就是TabHost标签页中上部 ...

  8. 修改phpcms会员登录后头部登陆条的会员名称不带括号

    phpcms会员登录后显示会员名称是带括号的,现在把他修改成不带括号. 找到函数库libs/functions/global.func.php,修改如下即可: function get_nicknam ...

  9. You need to use a Theme.AppCompat theme (or descendant) with this activity

    经过本人的经验和在网上查找,有2种方法可以解决. 解决步骤已经写到我的公众号,二维码在下面. 欢迎观看我的CSDN学院课程,地址:http://edu.csdn.net/course/detail/2 ...

  10. 2016.12.01 搭建dendroid备忘

    在2014年的时候看了freebuf的那篇,感觉很6,2014年搭了就一遍成功了,事过两年,物是人非啊,2016搞了云,没事测试,搞了一遍死活不成功,第二天测试成功,过程逗比坎坷,没什么难的 //环境 ...