node.js - Resetting the state after every integration test - Supertest, Nodejs, Typescript
问题描述
I am using supertest for writing integration-tests for POST Api: api/v1/students?id="someId"
which should throw a 4xx code if the id is already present.
import request from "supertest";
import { applyMiddleware, applyRoutes } from "../../src/utils";
import routes from "../../src/routes";
import errorHandlers from "../../src/middleware/errorHandlers";
describe("student routes", () => {
let router: Router;
beforeEach(() => {
router = express();
applyRoutes(routes, router);
applyMiddleware(errorHandlers, router);
});
afterEach(function () {
});
test("Create student", async () => {
const response = await request(router).post("/api/v1/students?id=lee");
expect(response.status).toEqual(201);
});
test("Create duplicate student test", async () => {
const response1 = await request(router).post("/api/v1/students?id=lee");
const response2 = await request(router).post("/api/v1/students?id=lee");
expect(response2.status).toEqual(409);
});
});
The problem is the first and second tests are not independent. The student with id lee
created in the first test is already present when the second test is run. I want to reset the express()
and make the tests independent of each other. How shall I proceed?
解决方案
您应该在每个单元测试用例之后清除内存数据库中的数据。
例如
app.ts
:
import express, { Router } from 'express';
const app = express();
const router = Router();
export const memoryDB: any = {
students: [],
};
router.post('/api/v1/students', (req, res) => {
const studentId = req.params.id;
const foundStudent = memoryDB.students.find((student) => student.id === studentId);
if (foundStudent) {
return res.sendStatus(409);
}
memoryDB.students.push({ id: studentId });
res.sendStatus(201);
});
app.use(router);
export default app;
app.test.ts
:
import request from 'supertest';
import app, { memoryDB } from './app';
describe('student routes', () => {
afterEach(() => {
memoryDB.students = [];
});
test('Create student', async () => {
const response = await request(app).post('/api/v1/students?id=lee');
expect(response.status).toEqual(201);
});
test('Create duplicate student test', async () => {
const response1 = await request(app).post('/api/v1/students?id=lee');
const response2 = await request(app).post('/api/v1/students?id=lee');
expect(response2.status).toEqual(409);
});
});
100%覆盖率的集成测试结果:
PASS src/stackoverflow/57565585/app.test.ts
student routes
✓ Create student (34ms)
✓ Create duplicate student test (17ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
app.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 4.276s, estimated 9s
源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57565585
推荐阅读
- javascript - 为什么 Google Chrome 中的 SpeechSynthesis.getVoices() 返回一个空列表?
- assembly - %eax, %edx, %ecx 在同一个函数框架中的使用规则
- python - 阻止 xml.etree 将特殊字符写入 HTML 代码
- mysql - 从多个表中获取所有列的最大值
- javascript - Ruby on Rails - Leaflet-rails 'ReferenceError: L is not defined'
- android - setTitleColor 在drawerlayout android studio内的backpress上不起作用
- shell - 使用 Windows 机器在 Mobaxterm 上编译 cpp 函数的 sh 文件
- r - 抽样随机行
- javascript - 无法在 Expo React 本机应用程序中清除间隔
- github - 我粘贴了用于克隆的 Github git URL,但得到:无法解析主机:github.com