使用 Jest 和 Super test 测试 NodeJs/Express API 🐧🐧
目录
关于测试!
Jest 与 SuperTest 介绍
谁應用測試?!
目录
测试是开发人员最重要的技能之一。很多人不教也不关注测试,但如果你已经了解测试,那么我必须在(2)部分尝试弄清楚它。你可以在文章《使用 Mocha 和 Chai 在 Express 中测试 Node JS (1)》中阅读更多内容。
关于测试!
单元测试
测试单个完全隔离的应用程序的统一性。
集成测试
测试单元及其依赖项的交互。例如,一个函数调用另一个函数意味着测试结果也取决于父函数中调用的函数。
端到端测试
完整流程测试。从前端按钮点击到 API 端点使用。
Jest 与 SuperTest 介绍
关于 Jest
- Jest 是Facebook创建的一个出色的测试库,用于帮助测试 JavaScript 代码、Express API、React 组件等。
- Jest 的优点在于它不仅具有与其他测试/断言库(如Jasmine 和 Chai)类似的语法。
- 使用 Jest,您的测试可以并行运行,因此执行速度比其他测试框架快得多。
关于 SuperTest
SuperTest 是一个 HTTP 断言库,可用于测试Node.js HTTP 服务器。
它建立在 SuperAgent 库之上,后者是 Node.js 的 HTTP 客户端。
谁應用測試?!
(1) 入门
因此,在本文中,我们将使用我使用 Express 和 Mongoose 构建的博客 REST API,
您可以在此处获取Github 仓库
- 要全局使用 jest,我们可以使用以下命令安装它
$ npm install -g --save-dev jest supertest
- 安装软件包后,我们需要在
package.json file
{
// ...
"scripts": {
"test": "jest"
}
// ...
}
(2)考试准备
- 编写您的第一个测试(您可以通过期望 1 === 1 来使测试通过)。```javascript
// 这通过了,因为 1 === 1
it('测试 Jest 是否有效', () => {
expect(1).toBe(1)
})
**(3) Testing Endpoints**
- Before you can test endpoints, you need to setup the server so Supertest can use it in your tests.
- Most tutorials teach you to listen to the Express app in the server file, like this:
```javascript
const express = require('express')
const app = express()
// Middlewares...
// Routes...
app.listen(3000)
- 这不起作用,因为它开始监听一个端口。如果您尝试写入多个测试文件,则会收到错误“port in use”。
- 因此,您希望允许每个测试文件自行启动服务器。为此,您需要导出不监听该应用程序的 app。
const express = require('express')
const app = express()
// Middlewares...
// Routes...
module.exports = app
- 出于开发或生产目的,您可以像平常一样在不同的文件中(例如 index.js)监听您的应用程序。```javascript
const app = require("./server");
app.listen(5000, () => {
console.log("服务器已启动!");
});
**(4) Using Supertest**
- To use Supertest, you require your app and supertest in the test file.
```javascript
const app = require("../server");
const mongoose = require("mongoose");
const supertest = require("supertest");
beforeEach((done) => {
mongoose.connect("mongodb://localhost:27017/JestDB",
{ useNewUrlParser: true, useUnifiedTopology: true },
() => done());
});
afterEach((done) => {
mongoose.connection.db.dropDatabase(() => {
mongoose.connection.close(() => done())
});
});
- 这些函数将在每个测试用例之前和之后调用。这使我们能够连接到 MongoDB 并在测试用例完成后删除所有数据。
-
在 Jest 中,这些是通过四种不同的函数完成的:
- beforeAll-在所有测试之前调用一次。
- beforeEach - 在每个测试之前调用(在每个测试函数之前)。
- afterEach - 在每次测试之后调用(在每个测试函数之后)。
- afterAll-所有测试后调用一次。
(5)使用路线
- 我们还想在 app 变量中初始化 Express 服务器,以便测试用例可以访问它。让我们创建一个名为 的新测试用例
GET /api/posts
。
test("GET /api/posts", async () => {
const post = wait Post.create({ title: "Post 1", content: "Lorem ipsum" });
await supertest(app).get("/api/posts")
.expect(200)
.then((response) => {
// 检查类型和长度
expect(Array.isArray(response.body)).toBeTruthy();
expect(response.body.length).toEqual(1);
// Check data
expect(response.body[0]._id).toBe(post.id);
expect(response.body[0].title).toBe(post.title);
expect(response.body[0].content).toBe(post.content);
});
});
* Here, we're adding a new document to our database so that we won't get an empty response. Then, we send a GET request using SuperTest to the /api/posts
endpoint and expect the response status to be 200
- which means success. Finally, we check if the response matches the data in the database.
We can now run our tests by running npm test
Matchers
Jest has quite a few functions used for assertions/expectations. You can see a full list here, but these are some common ones.
- toBeDefined
- toBeGreaterThan / toBeLessThan
-
toBe (uses === to compare)
-
toEqual (for deep object comparison)
-
toContain (see if a value is inside of a collection)
Now, let's test the get single post .
test("GET /api/posts/:id", async () => {
const post = await Post.create({ title: "Post 1", content: "Lorem ipsum" });
await supertest(app).get("/api/posts/" + post.id)
.expect(200)
.then((response) => {
expect(response.body._id).toBe(post.id);
expect(response.body.title).toBe(post.title);
expect(response.body.content).toBe(post.content);
});
});
</code></pre></div><h3>
<a name="we-can-now-run-our-tests-again-by-running-raw-npm-test-endraw-" href="#we-can-now-run-our-tests-again-by-running-raw-npm-test-endraw-">
</a>
We can now run our tests again by running <code>npm test</code>
</h3>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/i/1mvul58a5uawa4esdljw.PNG" alt="Alt Text"></p>
<h1>
<a name="conclusion" href="#conclusion">
</a>
Conclusion! <a name="chapter-4"></a>
</h1>
<p>I played around with testing lately. One thing I tried to do was to test the endpoints of my Express application.</p>
<p>If you enjoyed this article, please tell a friend about it!<br>
Share it on Twitter. If you spot a typo, I’d appreciate if you can correct it on <a href="https://github.com/mohamedlotfe/unit-testing-api-nodejs-jest">GitHub</a>.<br>
You can contact me through:</p>
<p>Gmail: <a href="mailto:mhmdlotfy9@gmail.com">mhmdlotfy9@gmail.com</a><br>
or <a href="https://www.linkedin.com/in/mohamedlotfybasher/">Linkedin</a><br>
Thank you</p>