如何在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>(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