簡體   English   中英

如何用 Jest 模擬 MongoDB ( mongoClient )

[英]How To Mock MongoDB ( mongoClient ) With Jest

我有一個 DBManager class 連接到 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();

我這樣稱呼它 class

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})
    }));

謝謝..

您可以使用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

您可以使用真實的 MongoDB 服務器在 package mongodb-memory-server的測試中使用。

所以在你的情況下,你只需要做:

import { MongoMemoryServer } from '../index';

describe('Single MongoMemoryServer', () => {
  let con;
  let mongoServer;

  beforeAll(async () => {
    mongoServer = await MongoMemoryServer.create();
    process.env.MONGODB_URL = mongoServer.getUri();
  });

  afterAll(async () => {
    if (con) {
      await con.close();
    }
    if (mongoServer) {
      await mongoServer.stop();
    }
  });

  it('DBManager connection', async () => {
    await DBManager.start();
    const db = DBManager.connection.db();
    // ...
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM