【问题标题】:How to unit test a custom repository of TypeORM in NestJS?如何在 NestJS 中对 TypeORM 的自定义存储库进行单元测试?
【发布时间】:2022-01-17 20:14:01
【问题描述】:

要测试的类

我的 TypeORM 存储库extendsAbstractRepository:

@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)

所以,我的问题是,如何模拟 repository 或 repository.findOne?

换句话说,我如何模拟从AbstractRepository 继承的字段,它们是protected,并且不能从UsersRepository 实例访问?

有一个similar question here,但它用于从Repository&lt;Entity&gt; 扩展而不是AbstractRepository&lt;Entity&gt;。他们能够模拟findOne,因为它是public。


我尝试了什么

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

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

【问题讨论】:

    标签: typescript unit-testing jestjs nestjs typeorm


    【解决方案1】:

    我选择了内存数据库解决方案。这样我就不必模拟 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)
        })
      })
    })
    

    【讨论】:

      猜你喜欢
      • 2021-06-07
      • 2021-08-07
      • 2022-07-07
      • 2019-11-27
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      相关资源
      最近更新 更多