首页 > 解决方案 > 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?

标签: node.jstypescriptexpresssupertest

解决方案


您应该在每个单元测试用例之后清除内存数据库中的数据。

例如

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


推荐阅读