Published on

Typescript 单元测试 | Jest | MongoMemoryServer | Mocha | Chai | Test | Supertest

Authors
  • avatar
    Name
    Shelton Ma
    Twitter

1. 使用 Jest 进行单元测试

Jest 是一个自带断言库、模拟功能和测试运行器的测试框架,因此不需要额外安装断言库.

  1. 安装

    # test via ts-jest
    npm install --save-dev jest ts-jest ts-node @types/jest
    npm install --save-dev mongodb-memory-server
    
  2. 在 package.json 中添加测试脚本

    {
      "scripts": {
        "test": "jest"
      }
    }
    
  3. 配置只测试

    // jest.config.ts
    export default {
      preset: "ts-jest",
      testEnvironment: "node",
      // 对源码测试, 覆盖率报告(coverage)也更合理,能对着源代码分析
      testMatch: ["**/src/**/*.test.ts"], 
    };
    
  4. 更多参数

    1. --verbose 显示详细信息
    2. --runInBand 并行显示
    3. --coverage 测试覆盖率
  5. 编写单元测试

    • 函数测试

      // 正常测试
      it("should generate project group number when previous projectGroupSerial exists", async () => {
        const projectGroup = {};
      
        const result = await generateProjectGroupNumber(
          projectGroup as Record<string, any>
        );
      
        expect(result).toEqual({
          projectGroupSerial: 1,
          projectGroupNumber: "xx",
        });
      });
      
      // 异常测试
      it("should raise Error when orgCode doesn't exists", async () => {
        await expect(generateProjectGroupNumber(projectGroup)).rejects.toThrow(
          "orgCode doesn't exists"
        );
      });
      
    • API 测试, 安装npm install jest supertest

      import request from 'supertest';
      import app from './app';
      
      describe('API Tests', () => {
        it('GET /api/hello should return "Hello World!"', async () => {
          const res = await request(app).get('/api/hello');
          expect(res.statusCode).toBe(200);
          expect(res.body).toEqual({ message: 'Hello World!' });
        });
      });
      
      
  6. 运行测试

    npm test
    
  7. 输出测试用例

    PASS  ./calculator.test.js
        ✓ should add two numbers correctly (3 ms)
        ✓ should add negative numbers correctly (1 ms)
        ✓ should add a positive and a negative number correctly (1 ms)
    
    PASS  ./app.test.js
        ✓ GET /api/hello should return "Hello World!" (40 ms)
    
      Test Suites: 2 passed, 2 total
      Tests:       4 passed, 4 total
      Snapshots:   0 total
      Time:        0.639 s, estimated 2 s
    

1. 使用MongoMemoryServer模拟数据

import mongoose from "mongoose";
import { MongoMemoryServer } from "mongodb-memory-server";

let mongoServer: MongoMemoryServer;

beforeAll(async () => {
  mongoServer = await MongoMemoryServer.create();
  const uri = mongoServer.getUri();
  await mongoose.connect(uri);

  // 模拟数据
  await Organization.create(mockOrgs);

  await ProjectGroup.create(mockProjectGroups);
});

afterAll(async () => {
  await mongoose.disconnect();
  await mongoServer.stop();
});

2. 使用 Mocha 和 Chai 进行单元测试

  1. 安装依赖

    npm install mocha chai --save-dev
    
  2. 如果你需要运行测试,可以在 package.json 中添加测试脚本

    {
      "scripts": {
        "test": "mocha"
      }
    }
    
  3. 编写待测试的代码

    // calculator.js
    function add(a, b) {
      return a + b;
    }
    
    module.exports = { add };
    
  4. 编写单元测试

    // test/calculator.test.js
    const { expect } = require('chai');
    const { add } = require('../calculator'); // 引入要测试的函数
    
    describe('Calculator', function() {
      it('should add two numbers correctly', function() {
        const result = add(2, 3);
        expect(result).to.equal(5); // 断言结果应该为 5
      });
    
      it('should add negative numbers correctly', function() {
        const result = add(-2, -3);
        expect(result).to.equal(-5); // 断言结果应该为 -5
      });
    
      it('should add a positive and a negative number correctly', function() {
        const result = add(2, -3);
        expect(result).to.equal(-1); // 断言结果应该为 -1
      });
    });
    
  5. 运行测试

    npm test
    
  6. 输出测试用例

    Calculator
        ✓ should add two numbers correctly
        ✓ should add negative numbers correctly
        ✓ should add a positive and a negative number correctly
    
    
      3 passing (10ms)