Testing in Nestjs
The Test
class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding.
createTestingModule
Test.createTestingModule()
takes a module metadata object as its argument. It returns a TestingModule
instance which in turn provides a few methods.
- to this method we pass an object that looks the same as when we are defining a
@Module
in a.module.ts
file.- we are really just trying to simulate the module in a minimalist way, where we include only what is needed for the particular test file.
- the resulting
TestingModule
is an isolated NestJS runtime. As a result, it gets all the NestJS behaviors like dependency injection.- for unit tests,
compile()
is the most important one, which bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventionalmain.ts
file usingNestFactory.create()
), and returns a module that is ready for testing.
- for unit tests,
The resultant TestingModule is limited to what you define when using the Test class (e.g. which providers
/controllers
you include)
- ex. if you pass
TweetsService
toproviders
, then you will get access to all of the methods insideTweetsService
.- you will want to make an instance of an injectable/controller:
service = module.get<TweetsService>(TweetsService);
Mocking
Imagine we have the following TestingModule:
const module: TestingModule = await Test.createTestingModule({
controllers: [UsersController],
providers: [UsersService]
}).compile()
If UsersService
has dependencies that need to be injected in order for it to work, we will get the Nest can't resolve dependencies
error. If we don't care about the dependencies of the UsersService
, we can simply mock it:
let controller: UsersController
const mockUsersService = {}
beforeEach(() => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UsersController],
providers: [UsersService]
})
.overrideProvider(UsersService)
.useValue(mockUsersService)
.compile()
service = module.get<TweetsService>(TweetsService);
})