在 NestJS 中对具有许多依赖项的服务进行单元测试

HMi*_*adt 3 unit-testing nestjs

在 Nest 中构建 API 时,我经常遇到一个问题,即特定 API 可能需要使用多个 Nest 模块来完成其工作。我想知道是否有更好的方法来构建我的模块,以便更轻松地对其进行单元测试。

例如,假设我们有一个OrderService. OrderService为了完成它的工作,它使用了一些不同的依赖项:

  • 它使用ProductsService来查找产品详细信息和价格。
  • 它使用UsersService来查找客户信息,例如 Stripe 客户 ID。
  • 它使用 Typeorm 来处理将数据Order写入数据库
  • 最后,假设它使用 aCouponsService来查找和验证 的优惠券详细信息Order

为了这个例子,我们假设这 4 个依赖项都是它自己的 Nest 模块。

当涉及到单元测试时OrdersService,我需要删除 4 个不同的依赖项。这似乎比应有的工作量多得多,所以我意识到必须有更好的方法。

我尝试做的一件事是创建单独的帮助程序文件来设置每个服务模拟。这减少了使用特定依赖项的每个服务的样板数量,但最终仍然会遇到 1 个服务可能有 4 个不同依赖项的情况。

理想情况下,我想实现某种模式或结构,以便在测试文件时,依赖关系要么非常简单,要么自动模拟,或者特定文件一次仅具有 1 个依赖关系,而不会过度简化系统。

我的问题实际上可以归结为:

如何在服务中处理像这样的许多依赖项,而又不会出现测试函数需要模拟 4 个以上方法的情况。我很想听听 Nest 的具体方法来做到这一点,但我也很欣赏任何通用的软件工程示例或模式来研究。

Jay*_*iel 6

有一个拉取请求允许使用 Nest 的@nestjs/testingpackage进行自动模拟,但它尚未被接受(尽管正在处理它!),并且有一个名为的包@golevelup/ts-jest允许您非常快速且轻松地设置对象的模拟。因此,您不必定义整个{ get: jest.fn(), create: jest.fn(), ...etc } useValue提供者,您可以像

const modFixture = await Test.createTestingModule({
  providers: [
    OrderService,
    {
      provide: ProductService,
      useValue: createMock<ProductService>(),
    },
    {
      provide: UserService,
      useValue: createMock<UserService>(),
    },
    ...etc
  ]
}).compile();
Run Code Online (Sandbox Code Playgroud)

所有方法都将设置为jest.fn()方法,可以根据您的具体测试进行扩展