如何在服务nestjs中模拟getMongoRepository

Posted

技术标签:

【中文标题】如何在服务nestjs中模拟getMongoRepository【英文标题】:How to mock getMongoRepository in service nestjs 【发布时间】:2019-12-01 00:16:05 【问题描述】:

我在nestjs 中为我的服务编写单元测试。在我的删除函数中,我使用getMongoRepository 删除。但是我坚持写单元测试

我已经尝试编写模拟但它不起作用

我的服务

 async delete(systemId: string): Promise<DeleteWriteOpResultObject> 
    const systemRepository = getMongoRepository(Systems);
    return await systemRepository.deleteOne( systemId );
  

我的模拟

import  Mock  from './mock.type';
import  Repository, getMongoRepository  from 'typeorm';

// @ts-ignore
export const mockRepositoryFactory: () => Mock<Repository<any>> = jest.fn(
  () => (
    save: jest.fn(Systems => Systems),
    delete: jest.fn(Systems => Systems),
    deleteOne: jest.fn(Systems => Systems),
  ),
);

我的测试

import  ExternalSystemService  from '../external-system.service';
import  Systems  from '../entities/external-system.entity';

module = await Test.createTestingModule(
      providers: [
        ExternalSystemService,
        
          provide: getRepositoryToken(Systems),
          useFactory: mockRepositoryFactory,
        ,
      ],
    ).compile();

    service = module.get<ExternalSystemService>(ExternalSystemService);
    mockRepository = module.get(getRepositoryToken(Systems));

 describe('delete', () => 
    it('should delete the system', async () => 
      mockRepository.delete.mockReturnValue(undefined);
      const deletedSystem = await service.delete(systemOne.systemId);

      expect(mockRepository.delete).toBeCalledWith( systemId: systemOne.systemId );
      expect(deletedSystem).toBe(Object);
    );

我收到了这个错误

ExternalSystemService › 删除 › 不应删除系统

ConnectionNotFoundError: Connection "default" was not found.

  at new ConnectionNotFoundError (error/ConnectionNotFoundError.ts:8:9)
  at ConnectionManager.Object.<anonymous>.ConnectionManager.get (connection/ConnectionManager.ts:40:19)
  at Object.getMongoRepository (index.ts:300:35)
  at Object.<anonymous> (external-system/tests/external-system.service.spec.ts:176:33)
  at external-system/tests/external-system.service.spec.ts:7:71
  at Object.<anonymous>.__awaiter (external-system/tests/external-system.service.spec.ts:3:12)
  at Object.<anonymous> (external-system/tests/external-system.service.spec.ts:175:51)

【问题讨论】:

【参考方案1】:

您应该避免使用全局函数,而应使用dependency injection 系统;这使得测试变得更加容易,并且是 Nest 的主要功能之一。

巢typeorm module已经提供了injecting a repository的便捷方式:

1) 在服务的构造函数中注入存储库:

constructor(
  @InjectRepository(Systems)
  private readonly systemsRepository: MongoRepository<Systems>,
) 

2) 使用注入的存储库

async delete(systemId: string): Promise<DeleteWriteOpResultObject> 
  return this.systemsRepository.deleteOne( systemId );

现在您的mocked repository 将用于您的测试。

【讨论】:

但是Repository 不能使用deleteOne 改用MongoRepository类型:github.com/typeorm/typeorm/blob/master/src/repository/…

以上是关于如何在服务nestjs中模拟getMongoRepository的主要内容,如果未能解决你的问题,请参考以下文章

带有模拟存储库的 Nestjs 服务测试不起作用

NestJS:如何在 canActivate 中模拟 ExecutionContext

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

服务的 NestJS 单元测试:模拟 getManager 导致“未找到连接“默认””错误

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

使用 NestJS 测试猫鼬模型