帶你入門帶你飛Ⅱ 使用Mocha + Chai + SuperTest測試Restful API in node.js

目錄
  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

 

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 ide

 

Example 1 - GET

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();
      });
  });

});

 

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 

相關文章
相關標籤/搜索