无法在Jest单元测试中模拟分页函数。

5
我正试图模拟我的服务的findAll函数。为此,我需要模拟myEntityRepository的findAndCount函数或nestjs-typeorm-paginate节点模块的paginate函数。findAll函数从表中获取记录列表,并使用NodeModule nestjs-typeorm-paginate 进行分页。
尝试一:模拟myEntityRepository 但它失败了,并显示错误和回溯信息。
    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),
}))


尝试2:模拟分页 然后我尝试模拟paginate方法,但仍然返回错误:
TypeError: 无法重新定义属性:paginate at Function.defineProperty()
我的.service.spec.ts与Pagination模拟更改)
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)
  })
  ...

在撰写这个问题之前: 我尝试了以下文章:
  1. 在Node模块的导出函数上使用 `jest.spyOn`
  2. 当未模拟模块时,如何在Jest中模拟已命名的导入函数
  3. https://github.com/nestjsx/nestjs-typeorm-paginate/issues/143
1个回答

4
我通过其他方式模拟外部模块来解决了这个问题:
我的.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

这对我的情况起作用。 我从https://dev59.com/xaDia4cB1Zd3GeqPDWxu#43090261中得到了一些想法。


1
你能展示一下在测试中如何调用这个吗?这将非常有帮助。 - NicoleZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接