typescript 如何在NestJS中对TypeORM的自定义仓库进行单元测试?

pbossiut  于 2023-04-13  发布在  TypeScript
关注(0)|答案(1)|浏览(191)

要测试的类

我的TypeORM存储库extends AbstractRepository:

@EntityRepository(User)
export class UsersRepository extends AbstractRepository<User> {

  async findByEmail(email: string): Promise<User> {
    return await this.repository.findOne({ email })
  }
}

单元测试

describe('UsersRepository', () => {
  let usersRepository: UsersRepository

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [UsersRepository]
    }).compile()

    usersRepository = module.get<UsersRepository>(UsersRepository)
  })

  describe('findByEmail', () => {
    it(`should return the user when the user exists in database.`, async () => {
      const fetchedUser = await usersRepository.findByEmail('test1@test.com')
    })
  })
})

在这里,我得到了错误:

TypeError: Cannot read property 'getRepository' of undefined

      at UsersRepository.get (repository/AbstractRepository.ts:43:29)
      at UsersRepository.findByEmail (users/users.repository.ts:11:23)
      at Object.<anonymous> (users/users.repository.spec.ts:55:49)

那么,我的问题是,我如何模拟repositoryrepository.findOne
换句话说,我如何模拟从AbstractRepository继承的字段,这些字段是protected,不能从UsersRepository示例访问?
有一个similar question here,但它是从Repository<Entity>而不是AbstractRepository<Entity>扩展的。他们能够模拟findOne,因为它是public

我所尝试的

我尝试以NestJS推荐的方式模拟它,但这是针对非自定义存储库的,在我的情况下不起作用:

{
  provide: getRepositoryToken(User),
  useValue: {
    findOne: jest.fn().mockResolvedValue(new User())
  }
}
cbjzeqam

cbjzeqam1#

我选择了内存数据库解决方案,这样我就不必模拟TypeORM的复杂查询,单元测试运行得一样快,而不会碰到真实的的数据库。
我的生产数据库是PostgreSQL,但我可以使用SQLite内存数据库进行单元测试。这是因为TypeORM提供了对数据库的提取。只要我们满足仓库的接口,我们在后台使用什么数据库并不重要。
下面是我的测试的样子:

const testConnection = 'testConnection'

describe('UsersRepository', () => {
  let usersRepository: UsersRepository

  beforeEach(async () => {
    const connection = await createConnection({
      type: 'sqlite',
      database: ':memory:',
      dropSchema: true,
      entities: [User],
      synchronize: true,
      logging: false,
      name: testConnection
    })

    usersRepository = connection.getCustomRepository(UsersRepository)
  })

  afterEach(async () => {
    await getConnection(testConnection).close()
  })

  describe('findByEmail', () => {
    it(`should return the user when the user exists in database.`, async () => {
      await usersRepository.createAndSave(testUser)
      const fetchedUser = await usersRepository.findByEmail(testUser.email)
      expect(fetchedUser.email).toEqual(testUser.email)
    })
  })
})

相关问题