nestjs 模拟导入模块

use*_*075 11 testing jestjs nestjs

我想测试我的AuthModule控制器HTTP层supertest作为官方描述Nestjs文档。此模块使用EmailServiceEmailModule.

我知道您可以按如下方式覆盖提供程序:

const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [
        AuthModule,
      ],
    })
      .overrideProvider(EmailService)
      .useValue(buildMock(EmailService))
Run Code Online (Sandbox Code Playgroud)

但是,这并不工作,我假设,因为EmailModule在进口AuthModule。一种解决方法是.overrideProvider(...).useValue(...)在每一个供应商EmailModule,但这种非意义,因为我接下来要由进口也模拟模块EmailModule

当我进行 e2e 测试时AuthModule,老实说,我并不关心它的EmailModule工作原理。我需要模拟的是EmailService并确保我的身份验证模块与该服务正确交互。

不幸的Test.createTestingModule({})是,没有.overrideModule()方法。

我试着EmailModule用开玩笑的方式嘲笑:

jest.mock('../../src/email/email.module.ts', () => {
  @Module({})
  class EmailModule {

  }

  return EmailModule;
});
Run Code Online (Sandbox Code Playgroud)

但我收到此错误:

Error: Nest cannot create the module instance. Often, this is because of a circular dependency between modules. Use forwardRef() to avoid it.

(Read more: https://docs.nestjs.com/fundamentals/circular-dependency)
Scope [RootTestModule -> AppModule]
Run Code Online (Sandbox Code Playgroud)

有谁知道这是如何实现的?

小智 6

我花了很长时间来尝试弄清楚如何模拟完整的 NestJS 模块。以下是对我有用的。

// Create a valid NestJS module to be used in place of the one we want to mock
@Module({})
class MockModule {}

// Identify the Module you want to mock and mock it
jest.mock('module-to-mock', () => {
  return {
    ModuleToMockName: {
      forRootAsync: jest.fn().mockImplementation(() => MockModule),
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

基本上,我们为 NestJS 提供了一个有效的模块,在这种情况下,该模块不执行任何操作,但可以编码为以可预测/可测试的方式运行。


小智 0

您是否尝试在测试模块中提供 EmailService ?它看起来像这样:

const module: TestingModule = await Test.createTestingModule({
  controllers: [AuthController],
  providers: [
    EmailService        
  ],
}).compile();
Run Code Online (Sandbox Code Playgroud)

我认为您可以跳过导入整个 EmailModule 并仅提供所需的内容