资讯专栏INFORMATION COLUMN

一步一步搭建react应用-node中使用 mocha + supertest + should 来

chengtao1633 / 3348人阅读

摘要:一步一步构建一个应用开篇地址是一个单元测试框架,类似于前端的语法也相近用来测试接口的库断言库,可读性很高搭建项目根目录下新建文件夹,中监听文件下的所有文件接口描述这里我们来测试一个添加一条电影的接口河正宇金允石郑满植动作犯罪

[一步一步构建一个react应用-开篇](https://segmentfault.com/a/11...

git地址

mocha 是一个node单元测试框架,类似于前端的jasmine,语法也相近

supertest 用来测试node接口的库

should nodejs断言库,可读性很高

搭建

npm install mocha should supertest --save-dev

项目根目录下新建test文件夹,movies.spec.js

package.json中

"scripts": {
    "start": "pm2 start ecosystem.config.js",
    "test": "mocha --watch" //监听 test文件下的所有文件
  },

接口描述

这里我们来测试一个添加一条电影的接口

    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字段

大体代码

/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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88487.html

相关文章

  • 步一搭建react应用-node使用 mocha + supertest + should

    摘要:一步一步构建一个应用开篇地址是一个单元测试框架,类似于前端的语法也相近用来测试接口的库断言库,可读性很高搭建项目根目录下新建文件夹,中监听文件下的所有文件接口描述这里我们来测试一个添加一条电影的接口河正宇金允石郑满植动作犯罪 [一步一步构建一个react应用-开篇](https://segmentfault.com/a/11... git地址 mocha 是一个node单元测试框架,类...

    dadong 评论0 收藏0
  • 步一步构建一个react应用-开篇

    摘要:线上地址主要从下面几点入手一步一步搭建应用前后端初始化爬取豆瓣电影的电影信息开启身份认证使用来做基于的用户身份认证中使用来写单元测试部署技术栈没用之后改运行代码到本地项目地址喜欢就一下吧前端后端需要安装本项目端口并开启权限认证。 介绍 断断续续利用周末时间做了两个月,基于react和express的一个小项目差不多做完了。所以想写一系列文章来总结一下前后端用到技术及遇到的问题和解决方法...

    BigTomato 评论0 收藏0
  • 步一步构建一个react应用-开篇

    摘要:线上地址主要从下面几点入手一步一步搭建应用前后端初始化爬取豆瓣电影的电影信息开启身份认证使用来做基于的用户身份认证中使用来写单元测试部署技术栈没用之后改运行代码到本地项目地址喜欢就一下吧前端后端需要安装本项目端口并开启权限认证。 介绍 断断续续利用周末时间做了两个月,基于react和express的一个小项目差不多做完了。所以想写一系列文章来总结一下前后端用到技术及遇到的问题和解决方法...

    lylwyy2016 评论0 收藏0
  • 步一搭建react应用-前后端初始化

    摘要:一步一步搭建应用项目初始化一步一步构建一个应用开篇地址前端初始化目录结构。。。。。。 一步一步搭建react应用-项目初始化 [一步一步构建一个react应用-开篇](https://segmentfault.com/a/11... git地址 前端初始化 # 目录结构 +----/build + +----/config + +----+/pu...

    fevin 评论0 收藏0
  • 步一搭建react应用-前后端初始化

    摘要:一步一步搭建应用项目初始化一步一步构建一个应用开篇地址前端初始化目录结构。。。。。。 一步一步搭建react应用-项目初始化 [一步一步构建一个react应用-开篇](https://segmentfault.com/a/11... git地址 前端初始化 # 目录结构 +----/build + +----/config + +----+/pu...

    MartinHan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<