目錄
1. 簡介
2. 準備開始
3. Restful API測試實戰
Example 1 - GET
Example 2 - Post
Example 3 - Put
Example 4 - Delete
4. Troubleshooting
5. 參考文檔html
通過上一篇文章的介紹,相信你已經對mocha, chai有必定的瞭解了, 本篇主要講述如何用supertest來測試nodejs項目中的Restful API, 項目基於express框架。node
SuperTest 是 SuperAgent一個擴展, 一個輕量級 HTTP AJAX 請求庫.web
SuperTest provides high-level abstractions for testing node.js API endpoint responses with easy to understand assertions.express
npm安裝命令npm
npm install supertest
nodejs項目文件目錄結構以下json
├── 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這個文件中app
測試依賴庫框架
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 ide
Controller/dashboard/widgets/index.jspost
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(); }); }); });
被測代碼:
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
被測代碼
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 作數據準備。
被測代碼
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
測試結果以下:
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
感謝閱讀,若是您以爲本文的內容對您的學習有所幫助,您能夠點擊右下方的推薦按鈕,您的鼓勵是我創做的動力。