Search code examples
node.jsmongodbtypescriptnestjstypeorm

How to mock getMongoRepository in service nestjs


I write unit test for my service in nestjs. In my function delete i use getMongoRepository to delete. But i stuck in write the unit test

I've tried write the mock but it's not work

my service

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

my mock

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

my test

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

I got this error

ExternalSystemService › delete › should not delete the system

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)

Solution

  • You should avoid using global functions and instead use the dependency injection system; this makes testing much easier and is one of the main features of nest.

    The nest typeorm module already provides a convenient way of injecting a repository:

    1) Inject the repository in your service's constructor:

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

    2) Use the injected repository

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

    Now your mocked repository will be used in your test.