-
Couldn't load subscription status.
- Fork 307
Closed
Labels
Description
🚀 Feature Proposal
Exclude ɵfac ɵprov properties from jest auto mock
Motivation
Currently, I'm trying to test a component that depends on an external Angular library. This library provides a SomeService that is provided in root.
Here is my component:
class Component {
someService = inject(SomeService);
method() {
this.someService.someMethod();
}
}Here is my test:
import { SomeService } from 'some-library';
jest.mock('some-library');
beforeEach(() => {
TestBed.configureTestingModule({
providers: [SomeService],
});
fixture = TestBed.createComponent(Component);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('test', () => {
component.method();
});Currently I receive error: Cannot read property 'someMethod' of undefined.
This happens because of jest auto mocks, mocking ɵfac and ɵprov as well. Is it possible to exclude them?
Example
I've done some research. Here is my working patch:
jest.mock(`some-library`, () => {
const moduleMock = jest.createMockFromModule(`some-library`);
function* walk(obj: unknown, walkedNodes: any[] = []): Generator<[key: string, target: any]> {
if ((typeof obj !== `function` && typeof obj !== `object`) || walkedNodes.includes(obj)) {
return;
}
for (const key in obj) {
if (typeof key === `string` && key.startsWith(`ɵ`)) {
yield [key, obj];
}
yield* walk(obj[key], [...walkedNodes, obj]);
}
}
for (const [key, target] of walk(moduleMock)) {
switch (key) {
case `ɵfac`: {
target[key] = () => new target();
break;
}
case `ɵprov`: {
if (target[key] === undefined) {
break;
}
if (`factory` in target[key]) {
target[key].factory = () => new target();
}
break;
}
}
}
return moduleMock;
});However, it would not be beneficial to repeat it in each test and mock. Perhaps it could be placed there?