I'm facing a Catch-22 involving the use of Angular's @Inject('Window')
in a web API service. When it's used with the Window injection in the service constructor, the test specs fail in the Jasmine/Karma environment as dependency injection fails for Window. If the @Inject isn't included, the test specs succeed, but running the code in localhost causes the same dependency injection error.
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(@Inject('Window') private w: Window) {...
In the test spec file, I'm mocking the Window object like this to set a custom location:
describe('ApiService', () => {
let service: ApiService;
let fakeW: Window;
beforeEach(waitForAsync(() => {
fakeW = <any> {
location: <any> new URL("https://test.environment.com/")
};
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{ provide: Window, useFactory: () => fakeW },
]
});
service = TestBed.inject(ApiService);
With the @Inject statement in the constructor, dependency injection fails:
ApiService should create FAILED
Failed: R3InjectorError(DynamicTestModule)[ApiService -> Window -> Window]:
NullInjectorError: No provider for Window!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'ApiService', 'Window', 'Window' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[ApiService -> Window -> Window]:
NullInjectorError: No provider for Window!
Removing the @Inject from the constructor and just using private w: Window
causes tests to succeed. However, it causes the same provider error when the code is run in localhost.
Do I just need to change how I'm mocking the Window object so that @Inject can work with it?