[一步一步構建一個react應用-開篇](https://segmentfault.com/a/11...前端
git地址node
mocha 是一個node單元測試框架,相似於前端的jasmine,語法也相近react
supertest 用來測試node接口的庫git
should nodejs斷言庫,可讀性很高github
npm install mocha should supertest --save-dev
項目根目錄下新建test文件夾,movies.spec.jsmongodb
package.json中數據庫
"scripts": { "start": "pm2 start ecosystem.config.js", "test": "mocha --watch" //監聽 test文件下的全部文件 },
這裏咱們來測試一個添加一條電影的接口npm
method: POST api: /api/movies document: { "title": 'movie0', "thumb": "public/p1075586949.jpg", "actors": [ "河正宇", "金允石", "鄭滿植" ], "type": [ "動做", "犯罪" ], "instruct": 'instruct...', "time": "2010-12-22(韓國)", }
這裏電影信息會保存到movies集合中,類型信息保存在types集合中
須要注意的是若是多條電影有相同的type,則同一個電影類型在collection中只存一次,但會inc count字段json
大致代碼segmentfault
/routes/movies.js
const MoviesModel = require('../models/movies_model') const CONFIG = require('../config/config') function callback(err, docs, res, next) { if (err) { next(err) return } res.json({ code: CONFIG.ERR_OK, data: docs }) } router.post('/', function (req, res, next) { MoviesModel.addMovies(req.body, (err, docs) => { callback(err, docs, res, next) }) });
/models/movies_model.js
const TypeModel = require('./type_model') class MoviesModel{ addMovies(data, callback) { const types = data.type DB.connect().then((db, err) => { TypeModel.addTypes(types, db) //保存分類 this.insertOne(db, data, callback) }).catch(e => { callback(e) }) } }
/models/type_model.js
class Type{ addTypes(typesArr, db) { const Types = db.collection('types') typesArr.forEach(item => { Types.update({ 'type_name': item }, { '$inc': { count: 1 } }, { upsert: true }) }) } }
測試中咱們錄入兩條電影信息,兩條的type字段中會有一個相同的類型
咱們要驗證的結論:
兩條電影都成功錄入,types集合中有三條document,"動做"的count是2,另兩條count是1
當前環境是test時,使用測試數據庫
/config/db.js let db_name='Movies' if(process.env.NODE_ENV=='test'){ db_name='Movies_test' } const url = f(`mongodb://%s:%s@localhost:3307/${db_name}?authMechanism=%s`, user, pwd, authMechanism)
測試數據
const movieInfo = { "title": 'movie0',"thumb": "public/p1075586949.jpg", "actors": [ "河正宇", ], "type": [ "動做", "犯罪" ], "instruct": 'instruct...',"time": "2010-12-22(韓國)", } const movieInfo1 = { "title": 'movie1',"thumb": "public/p1075586949.jpg", "actors": [ "河正宇", ], "type": [ "動做", "愛情" ], "instruct": 'instruct...',"time": "2010-12-22(韓國)", }
測試代碼
process.env.NODE_ENV = 'test' //運行時,會將當前環境設置爲test,鏈接數據庫時使用Movies_test庫,如上 const should = require('should') const request = require('supertest') const app = require('../app') describe('Movies Test',()=>{ describe('POST /movies',()=>{ //每一個it語句運行開始以前會插入數據 beforeEach(function (done) { request(app) //啓動node服務 .post('/api/movies').send(movieInfo).then(() => { return request(app).post('/api/movies').send(movieInfo1) }).then(res => { done() }) }) //每一個it語句運行完以後會清除表數據 afterEach(function (done) { MoviesModel.remove(() => { TypeModel.remove(() => { done() }) }) }) //測試錄入成功 it('add movie and get the added movie', function (done) { request(app) .get('/api/movies') .end((er, res) => { should(res.body.data).have.length(2) should(res.body.data[0]).have.property('title', 'movie1') done() }) }) //類型已經存在的就不在存了 it('repeat type not saved,will only increment count', function (done) { request(app) .get('/api/types') .then(res => { should(res.body.data).have.length(3) should(res.body.data[0]).have.property('count', 2) //"動做"的count是2 should(res.body.data[1]).have.property('count', 1) should(res.body.data[2]).have.property('count', 1) done() }) }) }) })
詳細完整的對每一個接口的測試見 test