10
votes

I'm trying to test my AuthModule controller HTTP layer with supertest as described in the official Nestjs documentation. This module uses an EmailService imported from an EmailModule.

I know you can override providers as follows:

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

but this doesn't work, I'm assuming because the EmailModule is imported in the AuthModule. A workaround is to .overrideProvider(...).useValue(...) every provider in the EmailModule, but this non sense as I'd then have to also mock modules imported by the EmailModule.

When I'm e2e testing the AuthModule, I honestly don't care about how the EmailModule works. All I should need to mock is the EmailService and make sure my auth module interacts with that service properly.

The Test.createTestingModule({}) doesn't have a .overrideModule() method, unfortunately.

I tried mocking the EmailModule with jest:

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

  }

  return EmailModule;
});

but I get this error:

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]

Does anyone know how this can be achieved ?

"I'm assuming because the EmailModule is imported in the AuthModule" No, overrideProvider allows overriding any provider in the context. Thus, if EmailService exists in your app context, it will be overriden. Could you show the @Module() part of the AuthModule and the EmailModule? - VinceOPS
Yes, overriding the EmailService isn't the problem. The problem I have is that I want to mock the entire Email module without having to mock everything thats imported and every provider of that module. My EmailModule exports an EmailService and uses an EmailRepository, so I'd have to mock both in this case. What I want is to tell the AuthModule to use a fake EmailModule, and I can provide the EmailService manually. - user5365075
Hi! Did you solve this issue? I'm facing the same problem here and I didn't find a solution yet. - Kiwanax
Nope, to this day I haven't found a solution, sorry :( - user5365075
I need a solution too, testing in nestjs is a pain because of this - boy