On NestJS application startup I am creating few db tables (using TypeORM
) and have written service file init-db.service.ts
for the same. The service file implements OnApplicationBootstrap
interface and onApplicationBootstrap
method is called once the application has fully started and is bootstrapped.
I am trying to write a unit test for the service file, but is unable to resolve PinoLogger
dependency while creating Testing Module. Please checkout below sample code:
Service file init-db.service.ts:
import {ConfigService} from '@nestjs/config';
import {PinoLogger} from 'nestjs-pino';
import {Injectable, OnApplicationBootstrap} from '@nestjs/common';
@Injectable()
export class InitDB implements OnApplicationBootstrap {
constructor(private readonly logger: PinoLogger, private readonly configService: ConfigService) {}
onApplicationBootstrap() {
this.someMethod();
}
async someMethod(): Promise<void> {
// code to create tables...
}
}
Unit test file init-db.service.spec.ts:
import {ConfigService} from '@nestjs/config';
import {Test, TestingModule} from '@nestjs/testing';
import {InitDB} from './init-db.service';
import {getLoggerToken, PinoLogger} from 'nestjs-pino';
const mockLogger = {
// mock logger functions
};
describe('InitDB', () => {
jest.useFakeTimers();
let configService: ConfigService;
let service: InitDB;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{
provide: getLoggerToken(InitDB.name), // <-------- PinoLogger dependency
useValue: mockLogger,
},
InitDB,
ConfigService,
],
}).compile();
service = module.get<InitDB>(InitDB);
configService = module.get<ConfigService>(ConfigService);
});
afterEach(() => {
jest.clearAllMocks();
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
Error Message:
Nest can't resolve dependencies of the BootstrapService (?, ConfigService). Please make sure that the argument PinoLogger at index [0] is available in the RootTestModule context.
Potential solutions:
- If PinoLogger is a provider, is it part of the current RootTestModule?
- If PinoLogger is exported from a separate @Module, is that module imported within RootTestModule?
@Module({
imports: [ /* the Module containing PinoLogger */ ]
})
I have already passed PinoLogger
at index [0], but the unit test still fails to resolve the dependency.
CodePudding user response:
Please note that you don't use @InjectPinoLogger
but you are trying to mock it as if you have used it.
You could either provide PinoLogger
as a dependency:
const module: TestingModule = await Test.createTestingModule({
providers: [
PinoLogger,
InitDB,
ConfigService,
],
}).compile();
or use @InjectPinoLogger
in your class constructor:
export class InitDB implements OnApplicationBootstrap {
constructor(
@InjectPinoLogger(InitDB.name)
private readonly logger: PinoLogger,
private readonly configService: ConfigService
) {}
}