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 ?
To mock an imported function with Jest we use the jest.mock () function. jest.mock () is called with one required argument - the import path of the module we're mocking.
One of the hallmarks of NestJS is making asynchronous programming very straightforward. Nest fully embraces Node.js Promises and the async/await paradigm. Coupled with Nest's signature Dependency Injection features, this is an extremely powerful combination. Let's look at how these features can be used to create dynamically configurable modules.
Briefly, the package wraps the MassiveJS library into a Nest module. MassiveJS provides its entire API to each consumer module (e.g., each feature module) through a db object that has methods like: db.myFunction () to execute scripts or database procedures/functions
A module is a class annotated with a @Module () decorator. The @Module () decorator provides metadata that Nest makes use of to organize the application structure. Each application has at least one module, a root module.
The way I solved this is by creating a TestModule
that is global:
@Global()
@Module({
providers: [
{
provide: EmailService,
useValue: {} // mock
},
],
})
class TestModule {}
Import the TestModule
at the beginning of your testing module:
const module = await Test.createTestingModule({
imports: [
TestModule,
AuthModule,
// ...
]
}).compile();
That way, the EmailService
is provided globally and you don't need to import the EmailModule
anymore.
Global modules are explained here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With