Tìm kiếm trang web

typescript - Không thể giả lập hàm Paginate trong các bài kiểm tra đơn vị jest


Tôi đang cố gắng mô phỏng hàm findAll của dịch vụ của mình. Để làm điều này, tôi cần mô phỏng hàm repository findAndCount của myEntityRepository hoặc hàm paginate của module Node nestjs-typeorm-paginate. Hàm findAll lấy danh sách các bản ghi từ bảng và được phân trang sử dụng NodeModule nestjs-typeorm-paginate.

Thử-1: Giả lập myEntityRepository nhưng nó thất bại với lỗi và theo dõi ngăn xếp:

    TypeError: queryBuilder.limit is not a function

      at ../node_modules/nestjs-typeorm-paginate/dist/paginate.js:119:28
      at ../node_modules/nestjs-typeorm-paginate/dist/paginate.js:8:71
      at Object.<anonymous>.__awaiter (../node_modules/nestjs-typeorm-paginate/dist/paginate.js:4:12)
      at paginateQueryBuilder (../node_modules/nestjs-typeorm-paginate/dist/paginate.js:115:12)
      at Object.<anonymous> (../node_modules/nestjs-typeorm-paginate/dist/paginate.js:22:15)
      at ../node_modules/nestjs-typeorm-paginate/dist/paginate.js:8:71

my.service.ts

import { IPaginationOptions, paginate, Pagination } from 'nestjs-typeorm-paginate'

export class MyService {
  constructor(@InjectRepository(MyEntity) private myEntityRepository: Repository<MyEntity>) { }

  async findAll(options: IPaginationOptions): Promise<Pagination<MyEntity>> {
    try {
      return await paginate<MyEntity>(this.myEntityRepository, options)
    } catch (error) {
      throw error
    }
  }
}

my.service.spec.ts

describe('MyService Basic GET findAll test cases', () => {
  let service: MyService
  let repositoryMock: MockType<Repository<MyEntity>>

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [MyService,
        {
          provide: getRepositoryToken(MyEntity), useFactory: repositoryMockFactory
        }
      ],
    }).compile()

    service = module.get<MyService>(MyService)
    repositoryMock = module.get(getRepositoryToken(MyEntity))

    const itemList = [{
        id: 1,
        my_field: 'a1',
    }, {
        id: 2,
        my_field: 'a2',
    }, ]

  it('should findAll() the MyEntity', async () => {
    expect((await service.findAll(options)).items.length).toBe(itemsList.length)
  })
})

const repositoryMockFactory: () => MockType<Repository<MyEntity>> = jest.fn(() => ({
  find: jest.fn(entity => entity),
  findAndCount: jest.fn(entity => entity),
}))

Thử-2: Giả lập paginate Sau đó tôi thử giả lập phương thức paginate nhưng vẫn trả về lỗi:

    TypeError: Cannot redefine property: paginate at Function.defineProperty (<anonymous>)

my.service.spec.ts với các thay đổi giả lập Phân trang)

import * as nestjsTypeormPaginate from 'nestjs-typeorm-paginate' // imported at top
  ....
  ....
  it('should findAll() the MyEntity', async () => {
    const queryDto: QueryMyEntityDto = { customerId: 1 }
    const options: IPaginationOptions = { page: 1, limit: 10 }
    let paginationMock = jest.spyOn(nestjsTypeormPaginate, 'paginate')
    paginationMock.mockImplementation((dto, options) => Promise.resolve({
      items: itemList.slice(0, 2),
      meta: {
        itemCount: 2,
        totalItems: 2,
        totalPages: 1,
        currentPage: 1,
      }
    }))
    repositoryMock.find.mockReturnValue(itemList)
    expect((await service.findAll(options)).items.length).toBe(itemsList.length)
  })
  ...

Trước khi viết câu hỏi này: Tôi đã thử theo dõi các bài đăng sau:

  1. Sử dụng `jest.spyOn` trên một hàm được xuất từ một module Node
  2. Cách giả lập hàm được đặt tên nhập khẩu trong Jest khi mô-đun không bị giả lập
  3. https://github.com/nestjsx/nestjs-typeorm-paginate/issues/143

Câu trả lời #1

Tôi đã giải quyết vấn đề này bằng cách giả lập module bên ngoài thông qua một cách khác:

my.service.spec.ts

// At the top level of your unit test file, before the import of the service

// Declare your itemList
const itemList = ['item1', 'item2', 'item3', 'item4'];

// Mock the external module and the paginate function
jest.mock('nestjs-typeorm-paginate', () => ({
  paginate: jest.fn().mockResolvedValue({
      items: itemList.slice(0, 2),
      meta: {
        itemCount: 2,
        totalItems: 2,
        totalPages: 1,
        currentPage: 1,
      }
    }),
}));

// ... unit tests

Điều này phù hợp với tình huống của tôi. Tôi đã lấy một số ý tưởng từ https://stackoverflow.com/a/43090261.

Bài viết liên quan