Having this mock service:
// /catalogue/__mock__/catalogue.service.ts
export const CatalogueService = jest.fn().mockImplementation(() => {
return {
filterRulesFor: jest.fn().mockImplementation((role: Roles): Rule[] => rules.filter(r => r.roles.includes(role))
fetchCountries: jest.fn().mockReturnValue(of(countriesStub())),
}
});
In the next scaffolding:
/catalogue
/__mock__
catalogue.service.ts
/tests
catalogue.controller.spec.ts
catalogue.module.ts
catalogue.controller.ts
catalogue.service.ts
I want to use the mock service inside the catalogue.controller.spec.ts:
// /catalogue/tests/catalogue.controller.spec.ts
import { CatalogueController } from '../catalogue.controller';
import { CatalogueService } from '../catalogue.service';
jest.mock('../catalogue.service'); // <----- manual mocking here
describe('CatalogueController', () => {
let controller: CatalogueController;
let service: CatalogueService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [UtilsModule],
controllers: [CatalogueController],
providers: [CatalogueService],
})
.compile();
controller = module.get<CatalogueController>(CatalogueController);
service = module.get<CatalogueService>(CatalogueService);
jest.clearAllMocks();
});
}
But when I try to use it:
describe('getCountries', () => {
let countries: Country[];
beforeEach(async () => {
service.fetchCountries()
.subscribe(countries => console.log(countries)); // <----- here
countries = await firstValueFrom(controller.getCountries());
});
it('should be called', () => {
expect(service.fetchCountries).toBeCalledTimes(1);
});
it('should not be empty', () => {
expect(countries.length).toBe(countriesStub().length);
});
});
It gives me TypeError: Cannot read property 'subscribe' of undefined as if the mock service does not have the functions defined.
If I write the mock right in the same file it just works but that's not what I want:
let controller: CatalogueController;
let service: CatalogueService;
// vvvvv Mock service here vvvv
const mockCatalogueService = {
filterRulesFor: jest.fn().mockImplementation((role: Roles): Rule[] => rules.filter(r => r.roles.includes(role))),
fetchCountries: jest.fn().mockReturnValue(of(countriesStub())),
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [UtilsModule],
controllers: [CatalogueController],
providers: [CatalogueService],
})
.overrideProvider(CatalogueService) // <--- Implementing here
.useValue(mockCatalogueService) // <--- and here
.compile();
controller = module.get<CatalogueController>(CatalogueController);
service = module.get<CatalogueService>(CatalogueService);
jest.clearAllMocks();
});
