Jest.js 模仿一个有很多依赖关系的NestJS服务--有没有更干净的方法?

dbf7pr2w  于 2023-11-15  发布在  Jest
关注(0)|答案(1)|浏览(159)

我正在为NestJS Controller编写单元测试,并试图模拟它的Service。我的测试套件目前运行良好,测试通过,但我想知道是否有一种更干净的方法来模拟Service,而不是我目前采用的方法。
我按照NestJS网站上的文档定义了一个mock工厂来应用于所有缺少的依赖项(NestJS说这对于你在一个类中有大量依赖项的情况很有用,并且mock所有这些依赖项将花费很长时间和大量的设置)。使用这种mock工厂方法,我手动mock我的服务中的每个方法,例如:{ findAll: jest.fn(), question: jest.fn(), questions: jest.fn() }.有没有更干净的方法来模拟这个服务,而不必手动声明该服务中的每个方法都等于jest.fn()?
我已经添加了我的代码的图像。谢谢大家!
code screenshot

kq4fsx7k

kq4fsx7k1#

在测试NestJS服务时,您的方法取决于您是进行单元测试还是集成测试,并且所涉及的依赖项的数量会显著影响您的策略。
1.**使用选择性模拟的集成测试:**如果您的目标是集成测试,并且您有多个依赖项,您可以选择仅模拟特定的依赖项。如代码片段所示,.useMocker方法允许选择性模拟。当您希望模拟某些依赖项(如示例中的AEService),同时允许其他依赖项与真实的示例交互时,此方法非常有用。为此,可以将@golevelup/ts-jestjest-mock-extended等自动模拟功能与useMocker结合使用。这些工具可以自动为您选择的依赖项创建模拟,从而简化设置过程。
1.**使用Automock进行单依赖或多依赖的单元测试:**如果您的服务有一个或多个依赖,并且您的目标是执行单独的单元测试(隔离测试服务),Automock是理想的选择。Automock无论您是将类与单个依赖或多个依赖隔离,都是有效的。它使用TypeScript Reflection API自动生成mock对象,从而简化测试过程。
下面是一个在依赖项的确切数量未知的场景中使用Automock的示例:

import { TestBed } from '@automock/jest';
 import { AEController } from './ae.controller';

 describe('AE Controller Unit Test', () => {
   let controller: AEController;
   let aeService: jest.Mocked<AEService>; // Mocked service

   beforeAll(() => {
     const { unit, unitRef } = TestBed.create(AEController).compile();
     controller = unit;
     aeService = unitRef.get(AEService); // Get the mocked service
   });

   test('should perform some action', () => {
     // Example test logic here
     controller.someMethod();
     expect(aeService.someServiceMethod).toHaveBeenCalled();
   });
 });

字符串
在本例中,Automock用于为AEController创建测试床,自动模拟AEService。此设置允许您在与其服务隔离的情况下测试控制器,无论AEService是唯一的依赖项还是众多依赖项之一。
总而言之,NestJS中的测试策略应该根据你是在进行单元测试还是集成测试以及你的服务与之交互的依赖数量来确定。对于选择性模拟的集成测试,使用.useMocker结合@golevelup/ts-jest等工具。对于单元测试,Automock提供了一种简化的方法来创建隔离的测试环境,不管你是处理一个依赖还是多个依赖。
参考文献:

相关问题