首页 > 解决方案 > Typeorm getRepository mockImplementation 返回模拟的 findOne 方法

问题描述

我正在使用带有 typeOrm 的nestjs
这是我要测试的方法。

属性生成器.ts

import { getRepository } from 'typeorm'
...

export class PropertyBuilder extends BasicEntityBuilder<PropertyDto, Property> {
  async onUpdatedOwner_id(entity: any, dtoField: string, propertyDto: PropertyDto) {
    if (dtoField !== 'owner_id') {
      throw new Error('dtoField is not valid')
    }
    entity[dtoField] = await getRepository(User).findOne({ id: propertyDto.owner_id })
  }
} 

PropertyBuilder.spec.ts

import ...

describe('PropertyBuilder', () => {
  let userRepository: Repository<User>

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        {
          provide: getRepositoryToken(User),
          useClass: Repository,
        },
      ],
    }).compile()

    userRepository = module.get(getRepositoryToken(User))
  })

  describe('onUpdatedOwner_id', () => {
    it('should set owner_id field with User object', () => {
      const expected: any = { name: 'user' }
      const entity: Property = new Property()
      const dto: PropertyDto = new PropertyDto()
      jest.spyOn(userRepository, 'findOne').mockResolvedValue(expected)
      new PropertyBuilder(Property).onUpdatedOwner_id(entity, 'owner_id', dto)
      expect(entity.owner_id).toBe(expected)
    })
  })
})

测试失败(node:952986) UnhandledPromiseRejectionWarning: ConnectionNotFoundError: Connection "default" was not found.

我知道我不应该提供任何东西......
我试过了

describe('onUpdatedOwner_id', () => {
    it('should set owner_id field with User object', () => {
      const expected: any = { name: 'user' }
      const entity: Property = new Property()
      const dto: PropertyDto = new PropertyDto()

      const getRepositoryMock = jest.fn() as jest.MockedFunction<typeof getRepository>
      getRepositoryMock.mockImplementationOnce(() => {
        return { findOne: jest.fn().mockResolvedValueOnce(expected) }
      })

      jest.spyOn(userRepository, 'findOne').mockResolvedValue(expected)
      new PropertyBuilder(Property).onUpdatedOwner_id(entity, 'owner_id', dto)
      expect(entity.owner_id).toBe(expected)
    })
  })

但它不起作用,因为 mockImplementation 它与 getRepository 的签名不兼容

Argument of type '() => { findOne: jest.Mock<any, any>; }' is not assignable to parameter of type '(entityClass: EntityTarget<unknown>, connectionName?: string) => Repository<unknown>'.

测试我的方法的正确方法是什么?

标签: typescriptnestjstypeorm

解决方案


您正在模拟 Nest 提供程序getRepositoryToken(User)(在 的 引擎盖下使用的是什么@InjectRepository(User),但不是getRepository您直接使用 in的 TypeORM 的实现PropertyBuilder。要直接用 jest 模拟一个包,您应该执行类似的操作

jest.mock('typeorm', () => ({
  getRepository: jest.fn().mockResolvedValue(expected)
})

它将最终被提升到文件顶部并在任何 TypeORM 导入之前运行,因此可以使用它。您也可以将所需的任何其他方法添加到({})退货中。


推荐阅读