开玩笑的猫鼬导致内存泄漏

时间:2020-09-12 20:21:41

标签: typescript mongoose async-await jestjs

更新2020-09-14

我有一个编写的示例测试用例。当我运行此代码时,测试用例通过了,但它抱怨teordown发生不正确,并且存在打开的连接。谁能看到它是什么?

方法1-内存泄漏

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection> = async MONGO_DB_NAME => {
  if (conn == null) {
    conn = await createConnection(__MONGO_URI__, {
      dbName: MONGO_DB_NAME,
      bufferCommands: false, // Disable mongoose buffering
      bufferMaxEntries: 0, // and MongoDB driver buffering
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true
    });
  }
  return conn;
};

const MONGO_DB_NAME = 'mongo-test';
let db: Connection;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async done => {
    db = await getConnection(MONGO_DB_NAME);
    done();
  });
  afterAll(async done => {
    if (conn) {
      await db.dropDatabase();
      await conn.close();
    }
    done();
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

错误:

工作进程无法正常退出,并且已被强制退出。这可能是由于拆卸不当导致测试泄漏所致。尝试使用--runInBand --detectOpenHandles运行以查找泄漏。

如果我把所有内容都剥下来,只是这样:

方法2-内存泄漏

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection> = async MONGO_DB_NAME => {
  if (conn == null) {
    conn = await createConnection(__MONGO_URI__, {
      dbName: MONGO_DB_NAME,
      bufferCommands: false,
      bufferMaxEntries: 0,
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true
    });
  }
  return conn;
};

const MONGO_DB_NAME = 'mongo-test';
let db: Connection;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
    console.log('db = ', db);
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

我还是有同样的问题

甚至用这种方法也遇到同样的问题:

方法3-内存泄漏

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection | null> = MONGO_DB_NAME =>
  new Promise(resolve => {
    if (conn == null) {
      conn = createConnection(__MONGO_URI__, {
        dbName: MONGO_DB_NAME,
        bufferCommands: false,
        bufferMaxEntries: 0,
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true
      });
      conn.on('connected', () => {
        console.log('connected?');
        resolve(conn);
      });
    }
    resolve(conn);
  });

const MONGO_DB_NAME = 'mongo-test';
let db: Connection;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
    console.log('db = ', db);
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

这种方法也有同样的问题

方法4-内存泄漏

import mongoose from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: typeof mongoose;

const getConnection: (MONGO_DB_NAME: string) => Promise<typeof mongoose> = async MONGO_DB_NAME => {
  if (!conn) {
    conn = await mongoose.connect(__MONGO_URI__, {
      dbName: MONGO_DB_NAME,
      // bufferCommands: false,
      // bufferMaxEntries: 0,
      // useNewUrlParser: true,
      // useUnifiedTopology: true,
      // useCreateIndex: true
    });
  }
  return conn;
};

const MONGO_DB_NAME = 'mongo-test';
let db: typeof mongoose;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
    console.log('db = ', db);
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

1 个答案:

答案 0 :(得分:1)

最终解决方案-谢谢:@EstusFlask

getMongoConnection.ts

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection | null> = MONGO_DB_NAME =>
  new Promise(resolve => {
    if (conn == null) {
      conn = createConnection(__MONGO_URI__, {
        dbName: MONGO_DB_NAME,
        bufferCommands: false,
        bufferMaxEntries: 0,
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true
      });
      conn.on('connected', () => {
        resolve(conn);
      });
    }
    resolve(conn);
  });

export default getConnection;

mytest.test.ts

import { Connection } from 'mongoose';
import getConnection from './getMongoConnection';

let db: Connection | null;

const MONGO_DB_NAME = 'mongo-test';
const collectionName = 'users';

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
  });
  afterAll(async () => {
    if (db) {
      await db.dropDatabase();
      await db.close();
    }
  });
  it('should insert a doc into collection', async () => {
    if (db) {
      const users = db.collection(collectionName);

      const mockUser = { _id: 'some-user-id', name: 'John' };
      await users.insertOne(mockUser);

      const insertedUser = await users.findOne({ _id: 'some-user-id' });
      expect(insertedUser).toEqual(mockUser);
    }
  });
});