【问题标题】:Dependencies when testing in NestJS在 NestJS 中测试时的依赖关系
【发布时间】:2022-01-31 01:35:50
【问题描述】:

正如 NestJS 中的第一个示例所示(https://docs.nestjs.com/fundamentals/testing),CatsController 的依赖项是 CatsService,因此他们创建了新的 CatService 实例并将其传递给 CatsController 的参数,就像馅饼一样简单。

在我的实际使用中,服务是系统的主要服务,它依赖于多个服务,这些服务依赖于其他服务,并且几乎所有服务(包括主要服务)都依赖于 TypeORM 的注入存储库。

在测试时我应该如何处理这种复杂的依赖注入?

一个例子:

Class MainService {
    constructor(
        @InjectRepository(SomeEntity1)
        private readonly someRepo1: Repository<SomeEntity1>,
        @InjectRepository(SomeEntity2)
        private readonly someRepo2: Repository<SomeEntity2>,
        @InjectRepository(SomeEntity3)
        private readonly someRepo2: Repository<SomeEntity3>,
        private readonly someService1: SomeService1,
        private readonly someService2: SomeService2,
        private readonly someService3: SomeService3,
        private readonly someService4: SomeService4,
        private readonly someService5: SomeService5,
        private readonly someService6: SomeService6,
        private readonly someService7: SomeService7,
        private readonly someService8: SomeService8,
        private readonly someService9: SomeService9
    ){}
}

Class SomeService1 {
    constructor(
        @InjectRepository(SomeEntity1)
        private readonly someRepo4: Repository<SomeEntity4>,
        @InjectRepository(SomeEntity2)
        private readonly someRepo5: Repository<SomeEntity5>,
        @InjectRepository(SomeEntity3)
        private readonly someRepo6: Repository<SomeEntity6>,
        private readonly someService4: SomeService4,
        private readonly someService5: SomeService10,
        private readonly someService9: SomeService11
    ){}
}

我可以在网上找到解决方案。 谢谢!

【问题讨论】:

  • 请提供一些关于您的问题的示例。
  • @omidh 添加了一个示例
  • 你必须模拟他们每个人,没有办法。但是通常单个模块中的依赖项过多并不是一个好兆头,请尝试将您的服务拆分为更小的模块。
  • 我同意你的观点,我有这种感觉已经有一段时间了。您认为有多少服务是一个好数字?
  • 没有明确的答案,但作为一般规则,尽量将服务/控制器行数保持在 100 左右。还要问问自己,您的课程是否只做一件事?如果不是,那么这是分裂的好兆头。即使在重构之后,您也可能需要一些依赖项,至少您只需要其中的一两个函数,因此您不需要模拟整个模块,只模拟您需要的函数。

标签: jestjs nestjs


【解决方案1】:

通常,当您进行单元测试时,您希望模拟依赖项,因为您希望将被测单元与应用程序的其余部分隔离开来。

Nest 提供了多种模拟方式,而 Jest 本人也提供了其他可能性 (https://jestjs.io/docs/es6-class-mocks)。

一种方法是使用自定义提供程序并提供您自己的模拟:

const module = await Test.createTestingModule({
  providers: [
    MainService,
    {
      provide: SomeService1
      useValue: MockSomeService1
    }
  ]
})
.compile()

MockSomeService1 可以是对象、类或工厂函数。更多详情请参考文档:https://docs.nestjs.com/fundamentals/custom-providers

如果您有很多依赖项,这可能是结合使用自动模拟和https://www.npmjs.com/package/@golevelup/ts-jest 的一个很好的用例。

import { createMock } from '@golevelup/ts-jest'

const module = await Test.createTestingModule({
  providers: [
    MainService
  ]
})
.useMocker(() => createMock())
.compile()

有关自动模拟的更多详细信息:https://docs.nestjs.com/fundamentals/testing#auto-mocking

【讨论】:

    猜你喜欢
    • 2021-01-30
    • 2020-10-30
    • 2018-09-01
    • 2011-04-22
    • 2021-06-04
    • 2019-09-12
    • 2020-06-14
    • 2021-10-12
    • 2019-12-01
    相关资源
    最近更新 更多