I have Nest.js app, where certain provider is injected into another provider:
export class AppService {
public constructor(private readonly appInnerService: AppInnerService) {}
}
AppService has a method publish
which calls appInnerService send
method. I created unit tests for AppService, where I want to mock AppInnerService provider:
describe('App service', () => {
let appService: AppService;
const appInnerService = {
send: jest.fn(),
};
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
providers: [AppService, AppInnerService],
})
.overrideProvider(AppInnerService)
.useValue(appInnerService)
.compile();
appService = moduleRef.get<AppService>(AppService);
});
it('should work', () => {
appService.publish({});
expect(appInnerService.send).toHaveBeenCalled();
});
}
Above code doesn't work, AppInnerService isn't injected into AppService, instead undefined is passed to constructor. Why above test isn't working and how can I fix it (without manually creating AppService class with mocked service, I want to use testing module created by @nestjs/testing package)?
For closure on the problem: AppService
needed to be decorated with @Injectable()
to get typescript to reflect the constructor parameter metadata. With just Injectable()
as was there, it's just a function call and not a decorator, so the metadata was not reflected and Nest could not act upon it.