【问题标题】:How To Mock MongoDB ( mongoClient ) With Jest如何用 Jest 模拟 MongoDB ( mongoClient )
【发布时间】:2021-08-26 17:16:49
【问题描述】:

我有一个 DBManager 类可以连接到 mongoClient

import { MongoClient } from 'mongodb';

class DBManager {
  private url = process.env.MONGODB_URL;

  private _connection: MongoClient;

  constructor() {
    this._connection = null;
  }
  get connection() {
    return this._connection;
  }

  async start() {
    if (!this._connection) {
      this._connection = await MongoClient.connect(this.url);
    }
  }
}

export default new DBManager();

我这样称呼这个类

await DBManager.start();
const db = DBManager.connection.db(); 

我在尝试模拟时收到此错误:

Received: [TypeError: db_manager_1.default.connection.db is not a function]

这是我使用的模拟方法:

  DBManager.start = jest.fn().mockResolvedValue(() => ({
      connection: jest.fn().mockReturnThis(),
      db: jest.fn().mockResolvedValue({success: true})
    }));

谢谢..

【问题讨论】:

    标签: node.js typescript unit-testing jestjs ts-jest


    【解决方案1】:

    您可以使用jest.spyOn(object, methodName, accessType?) 模拟DBManager.start() 方法和DBMananger.connection getter。

    例如

    dbManager.ts:

    import { MongoClient } from 'mongodb';
    
    class DBManager {
      private url = process.env.MONGODB_URL || '';
    
      private _connection: MongoClient | null;
    
      constructor() {
        this._connection = null;
      }
      get connection() {
        return this._connection;
      }
    
      async start() {
        if (!this._connection) {
          this._connection = await MongoClient.connect(this.url);
        }
      }
    }
    
    export default new DBManager();
    

    main.ts:

    import DBManager from './dbManager';
    
    export async function main() {
      await DBManager.start();
      const db = DBManager.connection!.db();
      db.collection('users');
    }
    

    main.test.ts:

    import { main } from './main';
    import DBManager from './dbManager';
    import { Db, MongoClient } from 'mongodb';
    
    describe('68888424', () => {
      afterEach(() => {
        jest.restoreAllMocks();
      });
      test('should pass', async () => {
        const mockDbInstance = ({
          collection: jest.fn(),
        } as unknown) as Db;
        const mockDb = jest.fn(() => mockDbInstance);
        jest.spyOn(DBManager, 'start').mockResolvedValueOnce();
        jest.spyOn(DBManager, 'connection', 'get').mockReturnValue(({ db: mockDb } as unknown) as MongoClient);
        await main();
        expect(DBManager.start).toBeCalledTimes(1);
        expect(DBManager.connection!.db).toBeCalledTimes(1);
        expect(mockDbInstance.collection).toBeCalledWith('users');
      });
    });
    

    测试结果:

     PASS  examples/68888424/main.test.ts (8.621 s)
      68888424
        ✓ should pass (5 ms)
    
    --------------|---------|----------|---------|---------|-------------------
    File          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    --------------|---------|----------|---------|---------|-------------------
    All files     |      75 |       50 |      50 |      75 |                   
     dbManager.ts |   57.14 |       50 |   33.33 |   57.14 | 12-17             
     main.ts      |     100 |      100 |     100 |     100 |                   
    --------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        9.532 s
    

    【讨论】:

    • 谢谢,@slideshowp 工作得很好当我像这样更改 DBManager 中的 getter 函数时,我应该如何编写测试? DBManager ``` 获取连接() { 返回 this._connection!.db(); } ``` main.ts ``` 从 './dbManager' 导入 DBManager;导出异步函数 main() { await DBManager.start(); const db = DBManager.connection; db.collection('用户'); } ```
    猜你喜欢
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 2021-02-15
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多