nestjs e2e+mongo setTimeOut踩坑

如何在e2e测试中使用mongo

  • 1 安装@shelf/jest-mongodb
npm i @shelf/jest-mongodb --dev
  • 2 在jest 配置文件中预配置@shelf/jest-mongodb
    test/jest-e2e.json
{
  "verbose": true,
  "moduleFileExtensions": ["js", "json", "ts"],
  "testEnvironment": "node",
  "testRegex": ".e2e-spec.ts$",
  "transform": {
    "^.+\\.(t|j)s$": "ts-jest"
  },
  
  "modulePaths": [
    "../"
  ],
  "preset": "@shelf/jest-mongodb",
}

  • 3 pakage json中增加配置,配置测试mongo版本:
 "config": {
        "mongodbMemoryServer": {
          "version": "4.4.1"
        }
      }
  • 4 编写测试代码
    test/test.e2e-spec.ts

import { Test } from '@nestjs/testing';
import { INestApplication, HttpModule } from '@nestjs/common';
import { MongoClient } from 'mongodb';
jest.useFakeTimers('legacy');
jest.setTimeout(200000);
describe('mongo (e2e)', () => {
  let app: INestApplication;
  let mqService: MqService;
  let connection;
  let db;
  beforeAll(async () => {
    const moduleFixture = await Test.createTestingModule({
      imports: [MqModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    mqService = moduleFixture.get(MqService);
    connection = await MongoClient.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
    db = await connection.db();
    await db.collection('users').deleteOne({ _id: '111'});
    await app.init();
  });

  function sleep(time) {
    for (const t = Date.now(); Date.now() - t <= time;);
  }

  describe('insertData', () => {
    test(`新增用户`, async () => {
      const body:any = { _id: '111', name:'jack '}
      await mqService.sendMessage('user-apply', body);
      sleep(1000)
      const user = await db.collection('users').findOne({ _id: '111'});
      expect(user.name).toEqual('jack');
    }); 
  });

  afterAll(async () => {
    await db.close();
    await app.close();
  });
});

  • 5 pakage json中增加命令:
"test:e2e": "jest --config ./test/jest-e2e.json  --watch"
  • 6 运行命令
    运行以下命令。来运行 test下的e2e的测试文件
npm run test e2e

timeout相关踩坑:

运行setTimeout相关的异步测试时,会发现代码运行报错,或者长时间没反应的现象,超时报错如下:
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout

  • 1 设置测试代码的超时时间
jest.setTimeout(200000);
  • 2 设置useFakeTimers
jest.useFakeTimers('legacy');
  • 3 修改timeout的方法, 不知道什么原因setTimout有时候代码运行回不来,改成死循环能暂时解决问题

旧: setTimeout

 async function sleep(time) {
    // Sleeping for a long time
    console.log(`Sleeping for ${ms/1000} seconds`);
    await new Promise(resolve => {
        setTimeout(resolve(), ms);
    })
  }

新: 死循环

 function sleep(time) {
    for (const t = Date.now(); Date.now() - t <= time;);
  }

参考:
https://jestjs.io/docs/en/mongodb
https://stackoverflow.com/questions/58828243/timeout-async-callback-was-not-invoked-jest-mongo-nestjs
https://jestjs.io/docs/en/api.html#testname-fn-timeout
https://stackoverflow.com/questions/62993577/jest-with-async-function-calls-before-and-after-settimeout

你可能感兴趣的:(nestjs e2e+mongo setTimeOut踩坑)