如何关闭nestjs服务中的数据库连接?

use*_*695 5 javascript testing jestjs nestjs

在我的数据库模块中,我正在创建与数据库的连接。通过这个设置我确实得到了错误

工作进程未能正常退出,已被强制退出。这可能是由于拆卸不当导致测试泄漏造成的。尝试使用 --runInBand --detectOpenHandles 运行来查找泄漏。

在我的 e2e 测试中。

我想我必须关闭连接。但是我如何client.closeonModuleDestroy()我的数据库模块中运行?

数据库模块.ts

import { Module } from '@nestjs/common'
import { MongoClient, Db, Logger } from 'mongodb'

@Module({
    providers: [
        {
            provide: 'DATABASE_CONNECTION',
            useFactory: async (): Promise<Db> => {
                const mongo = 'mongodb://localhost:27017'
                const database = 'testing'

                try {
                    Logger.setLevel('debug')

                    const client = await MongoClient.connect(mongo, {
                        useNewUrlParser: true,
                        useUnifiedTopology: true,
                    });

                    const db = client.db(database)
                    return db
                } catch (error) {
                    throw error
                }
            }
        },
        {
            provide: 'DATABASE_CLIENT',
            useFactory: () => true // how do I get client of the above provider?
        }
    ],
    exports: ['DATABASE_CONNECTION', 'DATABASE_CLIENT']
})

export class DatabaseModule {
    constructor(
        @Inject('DATABASE_CLIENT')
        private client: Db
    ) {}

    async onModuleDestroy() {
        console.log(this.client);
        // await this.client.close()
    }
}
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 7

打开的数据库连接是导致此问题的常见原因。模块需要自行清理,这尤其适用于模块可以多次实例化的测试。

client需要保留参考以进行清理。这可以通过单类服务来完成:

@Injectable()
class DatabaseConnection {
  async onModuleInit() {
    // ...same as DATABASE_CONNECTION factory
    this.client = client;
    this.db = client.db(database);
  }
  async onModuleDestroy() {
    await this.client.close()
  } 
}
Run Code Online (Sandbox Code Playgroud)

或者有两个工厂提供者,其中之一保留对以下内容的引用client

@Module({
  providers: [
    {
      provide: 'DATABASE_CLIENT',
      useFactory: () => ({ client: null })
    },
    {
      provide: 'DATABASE_CONNECTION',
      inject: ['DATABASE_CLIENT'],
      useFactory: async (dbClient) => {
        ...
        dbClient.client = client
        const db = client.db(database)
        return db;
      }
    }
  ]
  ...
})
export class DatabaseModule {
  constructor(@Inject('DATABASE_CLIENT') private dbClient) {}

  async onModuleDestroy() {
    await this.dbClient.client.close()
  } 
}
Run Code Online (Sandbox Code Playgroud)