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

Unit testing a service with many dependencies in NestJS

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

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

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

在对 OrdersService 进行单元测试时,我需要剔除 4 个不同的依赖项。这似乎比应该做的要多得多,所以我意识到必须有更好的方法。

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

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

我的问题归结为:

你如何在一个服务中处理许多像这样的依赖关系,而不至于最终导致测试一个函数需要你模拟 4 个以上的方法。我很想听听 Nest 特定的方法来做到这一点,但我也很感激任何通用的软件工程示例或模式来研究。

There's a pull request to allow for auto-mocking with Nest's @nestjs/testing package,但它还没有被接受(虽然正在努力!),并且有一个名为 @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();

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