How to mock the Knex in a test file of nestjs

57 views Asked by At

I am developing an API in Nest using Knex:

import { Injectable, NotFoundException } from '@nestjs/common'
import { InjectKnex, Knex } from 'nestjs-knex'
import { ICreatePersonData, IUpdatePersonData, Person } from './types'
import { PeopleUtils } from './people.utils'
import { ErrorsService } from 'src/shared/utils/errors.service'

@Injectable()
export class PeopleRepository {
  constructor(
    @InjectKnex() private readonly knex: Knex,
    private peopleUtils: PeopleUtils,
    private errorsService: ErrorsService
  ) {}

  async createPerson(createPersonData: ICreatePersonData): Promise<Person> {
    try {
      const {
        name,
        surname,
        personType,
        cpf,
        cnpj,
        birthDate,
        address,
        number,
        city,
        state,
        zipCode,
        complement,
        neighborhood,
        email,
        phone,
        cellphone
      } = createPersonData

      const [personId] = await this.knex('people').insert({
        name,
        surname,
        person_type: personType,
        cpf,
        cnpj,
        birth_date: birthDate,
        address,
        number,
        city,
        state,
        zip_code: zipCode,
        complement,
        neighborhood,
        email,
        phone,
        cellphone
      })
      const person = await this.findPersonById(personId)
      return person
    } catch (error) {
      throw this.errorsService.handleErrors(
        error,
        '#Não foi possível criar a pessoa',
        'repository/createPerson'
      )
    }
  }

I am trying to perform unit tests, but I am having difficulties mocking Knex. The test file looks like this (I am using Jest):

import { Test, TestingModule } from '@nestjs/testing'
import { PeopleUtils } from '../people.utils'
import {
  InternalServerErrorException
} from '@nestjs/common'
import { ICreatePersonData, IUpdatePersonData, Person } from '../types'
import { ValidatesService } from 'src/shared/utils/validates.service'
import { CreatePersonDto } from '../dto/create-person.dto'
import { UpdatePersonDto } from '../dto/update-person.dto'
import { PeopleRepository } from '../people.repository'

import { ErrorsService } from 'src/shared/utils/errors.service'
import { Knex } from 'knex'
import { InjectKnex, KnexModule, KnexModuleOptions } from 'nestjs-knex'

const knexModuleProvider = {
  provide: 'KnexConnection', 
  useValue: KnexModule.forRoot(mysqlConfig)
}

describe('PeopleRepository', () => {
  let peopleRepository: PeopleRepository
  let mockPeopleUtils: PeopleUtils
  let mockErrorsService: ErrorsService
  let mockKnex: KnexModule

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        PeopleRepository,
        {
          provide: PeopleUtils,
          useValue: {
            createPeopleArrayFromDB: jest
              .fn()
              .mockReturnValue([person1, person2])
          }
        },
        {
          provide: ErrorsService,
          useValue: {
            handleErrors: jest
              .fn()
              .mockReturnValue(new InternalServerErrorException())
          }
        },
        knexModuleProvider
      ]
    }).compile()

    peopleRepository = module.get<PeopleRepository>(PeopleRepository)
    mockPeopleUtils = module.get<PeopleUtils>(PeopleUtils)
    mockErrorsService = module.get<ErrorsService>(ErrorsService)
    mockKnex = module.get('KnexConection')
  })

  it('should be defined', () => {
    expect(peopleRepository).toBeDefined()
    expect(mockPeopleUtils).toBeDefined()
    expect(mockErrorsService).toBeDefined()
    expect(mockKnex).toBeDefined()
  })

  describe('createPerson', () => {
    it('should return a Person', async () => {
      //Arrange
      const createPersonData: ICreatePersonData = createPersonData1
      const expected: Person = person1
      jest
        .spyOn(mockErrorsService, 'handleErrors')
        .mockReturnValue(new InternalServerErrorException())

      //Act
      const result = await peopleRepository.createPerson(createPersonData)
      //Assert
      expect(result).toBeDefined()
      expect(result).toBeInstanceOf(Array)
      expect(result).toEqual(expected)
    })

At this moment, the code looks like this, but I have tried so many things that I think I don't even know what I'm doing anymore.

Has anyone done this and can help me?

It doesn't help, for example, to import the knexModule in the imports section because Nest doesn't allow mocking functions in imported modules.

0

There are 0 answers