使用Mocha&Chai测试节点/快速应用程序

您花了很多时间和精力来编写一个相当中等的应用程序,例如,使用大约1000行的代码库,并且您已经手动测试了该应用程序以确保一切正常。 您将代码推送到Github,然后有人决定为您的工作贡献自己的配额。 他们推送他们的代码,创建了一个拉取请求,然后您将其合并,现在您的应用程序不再运行,所有内容都被破坏了,这都是由于您合并了代码而造成的。另一种方法是避免此类问题以及软件附带的更多问题开发中,您需要将测试集成到您的工作流程中。

测试要求您编写测试,这些测试涵盖软件可能会收到的各种输入以及相应的输出。 这样,您可以确保应用程序按照您的预期运行,并且可以防止很多错误。 在将新代码添加到代码库之前编写测试始终很重要,这样可以确保新代码不会在代码库中引入任何错误,并且还可以帮助您事先了解新代码是否破坏了任何代码。您的代码库的一部分。

在本文中,我们将编写一个简单的Node / Express API应用程序,同时结合使用mocha&chai JavaScript测试包进行测试。

根据其网站上的描述, Mocha是一种测试框架,它使异步测试变得简单而有趣。 它将提供测试环境,使我们可以轻松运行chai。

Chai是可以与任何测试框架配对的断言库。 这是我们实际用来编写测试的库。

设置我们的示例应用程序

我们将构建一个应用程序,该应用程序从非持久性学生那里读取记录数据的信息。 要继续,我们需要创建以下文件和文件夹:

  ---控制器/ 
------ studentController.js
- -假/
------ students.js
---路线/
------ index.js
---测试/
------ test.js
-。babelrc
--- server.js
--- package.json

要设置虚拟数据,我们需要将数据包含在dummy / students.js文件中:

  const学生= [ 
{
编号:1
名称:“ Sean Grey”,
年龄:24岁
},
{
编号:2
名称:“ John Doe”,
年龄:26岁
},
{
id:3,
名称:'Janet Dane',
年龄:19岁
},
];
 出口默认学生; 

上面的代码块分配一个对象数组,每个对象都包含学生的详细信息。

现在,我们来设置package.json,这样我们就可以安装构建和测试应用程序所需的所有软件包。

  { 
“ name”:“学生记录”,
“ version”:“ 1.0.0”,
“ description”:“用于管理学生记录的API”,
“ main”:“ server.js”,
“ author”:“ Samuel Afolaranmi”,
“ license”:“ MIT”,
“脚本”:{
“ test”:“ mocha --require babel-register tests / *。js --exit”,
“ dev”:“ nodemon --exec babel-node --presets babel-preset-env ./server.js”
}
“依赖关系”:{
“ body-parser”:“ ^ 1.18.3”,
“表达”:“ ^ 4.16.3”
},
“ devDependencies”:{
“ babel-cli”:“ ^ 6.26.0”,
“ babel-preset-env”:“ ^ 1.7.0”,
“ chai”:“ ^ 4.1.2”,
“ chai-http”:“ ^ 4.0.0”,
“ mocha”:“ ^ 5.1.1”,
“ nodemon”:“ ^ 1.17.4”
}
}

在package.json文件中,我们包含了我们的mocha和chai,我们将使用它们来编写测试。 我们还需要包含chai-http,这是一个插件,可让我们使用chai断言运行HTTP集成。 现在,我们可以运行npm install来安装软件包,并准备完成设置应用程序。

下一步是创建路由和server.js文件,但是首先我们应该创建控制器文件,因为我们需要将其导入到路由文件中。 在controllers / studentController.js文件中,我们应该包括:

 从“ ../dummy/students.js”导入学生; 
 类StudentController { 
//获取所有学生
静态getAllStudents(req,res){
返回res.status(200).json({
学生们,
消息:“所有学生”,
});
}
  //得到一个学生 
静态getSingleStudent(req,res){
const findStudent = students.find(学生=> student.id === parseInt(req.params.id,10));
如果(findStudent){
返回res.status(200).json({
学生:findStudent,
消息:“单个学生记录”,
});
}
返回res.status(404).json({
消息:“未找到学生记录”,
});
}
}
 导出默认的StudentController; 

在controllers / studentController.js文件中,我们导入了虚拟数据,创建了一个类来保存我们的控制器方法,并为要使用该控制器类实现的每个对象创建了两个静态方法。 顾名思义,第一种方法getAllStudents获取我们在虚拟数据中拥有的所有学生记录,并以200 HTTP状态码返回它们,而第二种方法getSingleStudent获取单个学生的记录并以一个学生返回记录。 200 HTTP状态。 如果找不到记录,则返回404 HTTP状态代码。

现在我们已经设置了控制器,现在可以返回到路由和server.js了。 在我们的routes / index.js文件中,我们应该添加以下代码:

 从'express'导入{Router}; 
从'../controllers/studentController.js'导入StudentController;
  const路由= Router(); 
  route.get('/',StudentController.getAllStudents); 
route.get('/:id',StudentController.getSingleStudent);
 导出默认路由; 

我们从express导入Router(快捷路由器)并将其分配给路由,还从controllers / studentController导入了StudentController类。 js文件。 我们使用导入的路由器创建两个路由,这两个路由分别绑定到其相应的控制器方法。

现在,我们应该创建server.js文件,以便可以测试我们一直在编写的代码是否可行。

 从“快递”进口快递; 
从'body-parser'导入bodyParser;
从“ ./routes/index”导入路由;
  //实例化快递 
const app = express();
  //设置我们的端口 
const port = process.env.PORT || 8000;
  //将应用程序配置为用户bodyParser 
app.use(bodyParser.urlencoded({Extended:true}));
app.use(bodyParser.json());
  //在应用程序中注册我们的路线 
app.use('/',路线);
  //启动我们的服务器 
app.listen(port,()=> {
console.log(`服务器在端口$ {port}上启动);
});
  //导出我们的应用以进行测试 
导出默认应用程序;

因为我们正在编写ES6代码,所以我们需要babel来编译我们的代码,并且要使其正常工作,我们需要将以下代码添加到.babelrc文件中:

  { 
“预设”:[“ env”]
}

现在我们已经设置了所有应用程序,接下来可以运行npm run dev来运行我们的应用程序并使用Postman测试端点。

为我们的应用编写测试

我们的应用程序运行良好,但是我们需要为其编写测试。 为了确保我们不会破坏它,同时还涵盖了所有极端情况。 在我们的tests / test.js文件中,我们将编写测试。

  //导入依赖项以进行测试 
从“柴”进口柴;
从'chai-http'导入chaiHttp;
从“ ../服务器”导入应用;
  //配置柴 
chai.use(chaiHttp);
chai.should();
  describe(“学生”,()=> { 
describe(“ GET /”,()=> {
//测试以获取所有学生记录
它(“应该让所有学生记录下来,(完成)=> {
chai.request(app)
。得到('/')
.end((err,res)=> {
res.should.have.status(200);
res.body.should.be.a('object');
done();
});
});
  //测试以获取单个学生记录 
它(“应该获得一份学生记录”,(完成)=> {
const id = 1;
chai.request(app)
.get(`/ $ {id}`)
.end((err,res)=> {
res.should.have.status(200);
res.body.should.be.a('object');
done();
});
});

//测试以获取单个学生记录
它(“不应获得单个学生记录”,(完成)=> {
const id = 5;
chai.request(app)
.get(`/ $ {id}`)
.end((err,res)=> {
res.should.have.status(404);
done();
});
});
});
});

在文件的开头,我们导入了运行测试所需的所有软件包,然后将chai配置为使用chai-http插件。 我们还通过运行chai.should()将chai配置为使用should接口。 每个描述模块都用于将我们的测试分组在一起,以便于访问和组织。

第一个it块是在第一个端点上运行以从数据中获取所有学生记录的测试,它断言响应的状态应为200,并且应返回一个对象。 第二个it块是在第二个端点上运行以获取单个学生请求的测试。 假设该学生存在,则断言该响应的状态应为200,并且应返回一个对象。 最后,第三个it块是一个测试,该测试也在第二个端点上运行以获取单个请求。 假设该学生不存在,则断言该响应的状态应为404。

剩下的就是让我们运行npm run test ,我们将看到我们的测试通过。 美丽,不是吗?