如何使用 Jest 在 NestJS 的提供者中模拟和监视“mongoose.connect”

Posted

技术标签:

【中文标题】如何使用 Jest 在 NestJS 的提供者中模拟和监视“mongoose.connect”【英文标题】:How to use Jest to mock and spy a `mongoose.connect` in a provider of NestJS 【发布时间】:2020-11-04 14:10:12 【问题描述】:

我定义了一个特定于数据库的自定义 Module 以通过 Mongoose API 连接 MongoDB。

完整代码为here。

  
    provide: DATABASE_CONNECTION,
    useFactory: (dbConfig: ConfigType<typeof mongodbConfig>): Connection =>
      createConnection(dbConfig.uri, 
        useNewUrlParser: true,
        useUnifiedTopology: true,
        //see: https://mongoosejs.com/docs/deprecations.html#findandmodify
        useFindAndModify: false
      ),
    inject: [mongodbConfig.KEY],
  ,

在为这个提供者编写测试时,我想确认数据库连接已定义并监视connect 方法以验证调用的参数。

我确实需要手动模拟功能,但是有an issue which is closed suddenly。

更新:我尝试使用来自ts-jestmocked,但它不起作用。

describe('DatabaseProviders(Connectoin)', () => 
  let conn: any;

  jest.mock('mongoose', () => 
    return  createConnection: jest.fn() ;
  )

  beforeEach(() => 
    // provide a mock implementation for the mocked createConnection:
    mocked(createConnection).mockImplementation((uri: any, options: any) => 
      return  as any
    );
  );

  beforeEach(async () => 
    const module: TestingModule = await Test.createTestingModule(
      providers: [...databaseProviders],
    ).compile();

    conn = module.get<Connection>(DATABASE_CONNECTION);
  );

  afterEach(() => 
    mocked(createConnection).mockClear();
  );

  it('DATABASE_CONNECTION should be defined', () => 
    expect(conn).toBeDefined();
  );

  it('connect is called', () => 
    expect(conn).toBeDefined();
    expect(mocked(createConnection).mock.calls.length).toBe(1)
  )

);

在运行应用程序时,它会报错:

TypeError: utils_1.mocked(...).mockImplementation is not a function

【问题讨论】:

嘿!你想清楚了吗? @kuzzmi 是的,它在我的示例项目中工作,检查hantsy/nestjs-sample(100% 覆盖率)。 【参考方案1】:

在研究了一些资源并阅读了 Jest 文档后,我自己解决了这个问题。


jest.mock('mongoose', () => (
    createConnection: jest.fn().mockImplementation(
      (uri:any, options:any)=>( as any)
      ),
    Connection: jest.fn()
  ))

import  ConfigModule  from '@nestjs/config';
import  Test, TestingModule  from '@nestjs/testing';
import  Connection, createConnection  from 'mongoose';
import mongodbConfig from '../config/mongodb.config';
import  databaseConnectionProviders  from './database-connection.providers';
import  DATABASE_CONNECTION  from './database.constants';

describe('DatabaseConnectionProviders', () => 
  let conn: any;

  beforeEach(async () => 
    const module: TestingModule = await Test.createTestingModule(
      imports: [ConfigModule.forFeature(mongodbConfig)],
      providers: [...databaseConnectionProviders],
    ).compile();

    conn = module.get<Connection>(DATABASE_CONNECTION);
  );



  it('DATABASE_CONNECTION should be defined', () => 
    expect(conn).toBeDefined();
  );

  it('connect is called', () => 
    //expect(conn).toBeDefined();
    //expect(createConnection).toHaveBeenCalledTimes(1); // it is 2 here. why?
    expect(createConnection).toHaveBeenCalledWith("mongodb://localhost/blog", 
      useNewUrlParser: true,
      useUnifiedTopology: true,
      //see: https://mongoosejs.com/docs/deprecations.html#findandmodify
      useFindAndModify: false
    );
  )

);

查看完整代码here。

【讨论】:

以上是关于如何使用 Jest 在 NestJS 的提供者中模拟和监视“mongoose.connect”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Jest 和 NestJS 模拟 Mongoose 的“lean()”查询?

在 NestJS 中使用 Jest 和 MongoDB 进行单元测试

如何用 jest 在服务 (NestJS) 中测试模型 (Mongoose)

NestJS Jest 找不到具有绝对路径的模块

如何使用 jest 测试 HttpService.Post 调用

用 jest @nestjs 运行 e2e 测试