I perfome some e2E test in nestJs microservice (using Redis as transporter). Everything is going well except that the process never end.
This is the message displayed on console
Ran all test suites.
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
Here is the code of my controller
import {Body, Controller, HttpCode, Post, Query} from '@nestjs/common';
import { AppService } from './app.service';
import {Client, ClientProxy, MessagePattern, Transport} from '@nestjs/microservices';
import {AdminDto} from "./admin.dto";
import {Admin} from "./admin.interface";
import {Observable} from "rxjs";
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
/** Useful for test only **/
@Client({ transport: Transport.REDIS })
client: ClientProxy;
@Post()
@HttpCode(200)
call(@Query('command') cmd, @Body() data: any): Observable<any> {
return this.client.send<number>({ cmd }, data);
}
/** End of test **/
@MessagePattern({cmd: 'createAdmin'})
async createClient(adminDto: AdminDto): Promise<Admin> {
return await this.appService.create(adminDto);
}
}
And this is my app.e2e-soec.ts file, as you can see, I close all connection on afterEach fuction.
import { Test } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import {Transport} from "@nestjs/microservices";
import {AppModule} from "../src/app.module";
import * as mongoose from "mongoose";
import {connection} from "mongoose";
describe('AppController (e2e)', () => {
let server;
let app: INestApplication;
beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication();
server = app.getHttpAdapter().getInstance();
app.connectMicroservice({
transport: Transport.REDIS,
options: {
url: 'redis://0.0.0.0:6379',
},
});
await app.startAllMicroservicesAsync();
await app.init();
});
it(`/POST (create admin)`, done => {
const adminDto = {
firstName : 'test',
lastName: 'toto',
password: '1234',
email: 'test@toto.fr',
roles: ['ROLE_ADMIN']
};
return request(server)
.post('/?command=createAdmin')
.send(adminDto)
.end((error, response) => {
expect(response.status).toEqual(200);
expect(response.body).toMatchObject({
_id: expect.any(String),
firstName: "test",
lastName: "toto"
});
done();
});
});
afterEach(async done => {
await mongoose.connection.close();
await connection.close();
await app.close();
done();
});
});
EDIT
As Jesse Carter advice, I've added leaked-handles to get more clues
Seems it's because of redis
tcp handle leaked at one of:
at RedisClient.Object.<anonymous>.RedisClient.create_stream (/Users/myUser/project/admin-service/node_modules/redis/index.js:195:31)
tcp stream {
fd: 38,
readable: true,
writable: true,
address: { address: '127.0.0.1', family: 'IPv4', port: 54468 },
serverAddr: null
}