I have an Angular app with Jest and all tests are working just fine. A component injects a service:
component.ts:
import { FooService } from '../../services/foo.service'; // relative import
constructor(private foo: FooService) {}
component.spec.ts:
import { FooService } from '@services/foo.service'; // alias import
describe('FooComponent', () => {
let component: FooComponent;
let fixture: ComponentFixture<FooComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [....],
providers: [ { provide: FooService, useValue: { bar: () => {} } ],
declarations: [FooComponent],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
....
}));
});
Where both imports refer to the same foo.service.ts
, but using different form of import: TypeScript alias vs relative path.
Alias is defined in tsconfig.json:
"paths": {
"@services/*": ["./app/services/*"]
}
And Jest config:
"moduleNameMapper": {
"@services/(.*)": "<rootDir>/src/app/services/$1"
}
I have switched to nx workspace and the test started to fail with an error saying that there is no provider for FooService:
NullInjectorError: R3InjectorError(DynamicTestModule)[FooService -> FooService]:
NullInjectorError: No provider for FooService!
I have managed to fix it using same form of import - both the service and the test must use either alias import or relative import.
I would like to understand what is the problem here. It looks like Angular/Jest is making injection token / dependency resolvement based on TypeScript path (in Nx workspace). Is there any explanation how this works?