Angular/Jasmine中@Inject('Window')引发的依赖注入矛盾问题
解决Angular中Window注入的测试与运行冲突问题
你的问题核心是注入令牌不匹配:服务里用@Inject('Window')指定了字符串令牌,但测试配置里提供的是Window类作为令牌,两者无法对应,导致依赖注入失败。
修复方案(二选一即可)
方案1:修改测试配置,匹配字符串令牌
保持服务代码不变,将测试中的提供者配置改为使用字符串令牌'Window',和服务中的@Inject('Window')对应:
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: [ // 把Window改成'Window',匹配服务中的注入令牌 { provide: 'Window', useFactory: () => fakeW }, ] }); service = TestBed.inject(ApiService); })); // 测试用例... });
方案2:统一使用Window类令牌(更规范)
如果不想用字符串令牌,可以调整服务和全局提供者:
- 修改服务构造函数,移除
@Inject('Window'):
@Injectable({ providedIn: 'root' }) export class ApiService { constructor(private w: Window) { ... } }
- 在
app.module.ts中添加Window类的全局提供者,确保本地运行时能注入:
import { NgModule } from '@angular/core'; @NgModule({ // ...其他配置 providers: [ { provide: Window, useValue: window } ] }) export class AppModule { }
- 测试配置保持你原来的写法即可(此时服务注入的是Window类,测试中提供的也是Window类令牌,能正常匹配)。
为什么之前会出现两难情况?
- 保留
@Inject('Window')时:测试里提供的是Window类令牌,和服务的字符串令牌不匹配,DI找不到对应提供者,测试失败。 - 移除
@Inject时:测试里提供的Window类令牌能匹配服务的注入类型,测试通过;但本地运行时Angular默认不知道如何注入Window类,所以报错。
内容的提问来源于stack exchange,提问作者Carter Smith
相关产品推荐
相关产品推荐

