When setting up a mock service like this:
// /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 upcoming structure:
/catalogue
/__mock__
catalogue.service.ts
/tests
catalogue.controller.spec.ts
catalogue.module.ts
catalogue.controller.ts
catalogue.service.ts
The goal is to utilize the mock service within 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();
});
}
However, encountering an issue when attempting 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);
});
});
Getting a
TypeError: Cannot read property 'subscribe' of undefined
as though the mock service doesn't have the required functions defined.
If including the mock directly in the same file it works, but that's not the preferred approach:
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();
});