【一步步搭建一个react应用-开头】(https://segmentfault.com/a/11...git地址mocha是一个node单元测试框架,类似前端jasmine,语法也类似tosupertest用于测试节点接口库shouldnodejs断言库,可读性强buildnpminstallmochashouldsupertest--save-dev在项目根目录下新建test文件夹,movies.spec.jspackage中的“scripts”.json:{"start":"pm2startecosystem.config.js","test":"mocha--watch"//监控测试文件下的所有文件},接口说明这里我们测试一个接口添加一个movie方法:POSTapi:/api/moviesdocument:{"title":'movie0',"thumb":"public/p1075586949.jpg","actors":["HaJungWoo","KimYoonSeok","JungManSik"],"type":["Action","Crime"],"instruct":'instruct...',"time":"2010-12-22(Korea)",}电影这里的信息会保存在movies集合中,类型信息会保存在types集合中需要注意的是,如果多部电影有相同的类型,相同的电影类型只会在集合中保存一次,但是将inc计数字段通用代码/routes/movies.jsconstMoviesModel=require('../models/movies_model')constCONFIG=require('../config/config')functioncallback(err,docs,res,下一个){如果(错误){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.jsconstTypeModel=require('./type_model')classMoviesModel{addMovies(data,callback){consttypes=data.typeDB.connect().then((db,err)=>{TypeModel.addTypes(types,db)//保存分类this.insertOne(db,data,callback)}).catch(e=>{callback(e)})}}/models/type_model.jsclassType{addTypes(typesArr,db){constTypes=db.collection('types')typesArr.forEach(item=>{Types.update({'type_name':item},{'$inc':{count:1}},{upsert:true})})}}测试在测试中,我们输入了两条电影信息,两者的类型字段将具有相同的类型。我们要验证的结论:两部电影都成功进入,types集合中有3个文档,“action”两个的count为2,另外两个count为1。当前环境test时,使用测试数据库/config/db.jsletdb_name='Movies'if(process.env.NODE_ENV=='test'){db_name='Movies_test'}consturl=f(`mongodb://%s:%s@localhost:3307/${db_name}?authMechanism=%s`,user,pwd,authMechanism)测试数据constmovieInfo={"title":'movie0',"thumb":"public/p1075586949.jpg","actors":["HaJung-woo",],"type":["action","crime"],"instruct":'instruct...',"time":"2010-12-22(Korea)",}constmovieInfo1={"title":'movie1',"thumb":"public/p1075586949.jpg","actors":["何正宇",],"type":["action","love"],"instruct":'instruct...',"time":"2010-12-22(Korea)",}测试代码流程。env.NODE_ENV='test'//运行时会设置当前环境为test,连接数据库时会使用Movies_test库,如上constshould=require('should')constrequest=require('supertest')constapp=require('../app')describe('电影测试',()=>{describe('POST/movies',()=>{//数据会在每个it语句运行之前插入beforeEach(function(done){request(app)//启动节点service.post('/api/movies').send(movieInfo).then(()=>{returnrequest(app).post('/api/movies').send(movieInfo1)}).then(res=>{done()})})//每执行一次it语句,表数据都会被清空afterEach(function(done){MoviesModel.remove(()=>{TypeModel.remove(()=>{done()})})})//测试输入成功it('添加电影并获取添加的电影',function(done){request(app).get('/api/movies').end((er,res)=>{应该(res.body.data).have.length(2)应该(res.body.data[0]).have.property('title','movie1')done()})})//class已经存在的类型将不再存在it('repeattypenotsaved,willonlyincrementcount',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)//“action”的计数为2should(res.body.data[1]).have.property('count',1)should(res.body.data[2]).have.property('count',1)done()})})})})具体每个接口的完整测试见测试
