Search code examples
jestjsnestjstypeormts-jest

Not able to mock createQueryBuilder functions typeorm nestjs jest


I am trying to write unit test cases for my service file. There is a function linkDevice that joins 2 tables user and device and returns the object. I check if the device is already assigned to the user or not. If it is assigned I throw a BadRequestExcpetion and if not I add it to the user.

I tried adding a mockResolvedValue to the where function but it gave the following error

 TypeError: Cannot read property 'mockResolvedValue' of undefined

      129 |       new BadRequestException(),
      130 |     );
    > 131 |     profileRepository.createQueryBuilder.where.mockResolvedValue();
          |                                                ^
      132 |     const result = await service.linkDevice(device, 2);
      133 |     console.log(result);
      134 |     expect(service.linkDevice).toHaveBeenCalledWith(device, 2);

service.spec.ts

 beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        ProfileService,
        {
          provide: getRepositoryToken(Profile),
          useValue: {
            create: jest.fn(),
            save: jest.fn(),
            findOne: jest.fn(),
            createQueryBuilder: jest.fn(() => ({
              where: jest.fn().mockReturnThis(),
              setParameter: jest.fn().mockReturnThis(),
              leftJoinAndSelect: jest.fn().mockReturnThis(),
              getOne: jest.fn().mockReturnThis(),
            })),
          },
        },
      ],
    }).compile();

    service = module.get<ProfileService>(ProfileService);
    profileRepository = module.get(getRepositoryToken(Profile));
  });

 it('should throw error if device is already linked to profile', async () => {
    profileRepository.createQueryBuilder.mockResolvedValue(
      new BadRequestException(),
    );
    const result = await service.linkDevice(device, 2);
    console.log(result);
    expect(service.linkDevice).toHaveBeenCalledWith(device, 2);
  });

Error

  TypeError: this.profileRepository.createQueryBuilder(...).where is not a function

      55 |     const user = await this.profileRepository
      56 |       .createQueryBuilder('profile')
    > 57 |       .where('profile.id = :id')
         |        ^
      58 |       .setParameter('id', userId)
      59 |       .leftJoinAndSelect('profile.device', 'device')
      60 |       .getOne();

      at ProfileService.linkDevice (../src/modules/profile/profile.service.ts:57:8)
      at Object.<anonymous> (profile.service.spec.ts:131:34)

Solution

  • If you're looking to throw the error, you should use mockRejectedValue instead of mockResolvedValue. You also probably want to use mockRejectedValueOnce specificially, otherwise you're overriding the mock you set up from before. Otherwise your mock setup looks fine.