Angular 4迁移至9后Login组件Jasmine测试报'unreachable'错误求助
问题排查与解决方案
首先看你遇到的unreachable错误,这是Angular测试中依赖注入失败的典型表现,结合你的代码,我找到了几个关键问题:
1. AlertsService 导入被注释但仍在使用
你把AlertsService的导入语句注释掉了,但在测试代码的providers数组和alertService变量声明里还在引用它。Angular无法找到这个服务的定义,会导致注入链断裂,触发这个错误。
2. UserService 的 Provider 配置错误
你对UserService使用了useClass,但传入的是一个jasmine spy对象:
{ provide: UserService, useClass: userServiceSpy }
useClass的作用是告诉Angular用指定的类来创建实例,但userServiceSpy是一个已经创建好的spy对象,不是类。这里应该和AuthService一样使用useValue。
3. PrimeNG组件的声明方式错误
你手动在declarations里添加了Dialog, Header, Footer这些PrimeNG组件,这是不正确的。这些组件属于PrimeNG的官方模块,应该通过导入对应的模块(比如DialogModule)来引入,而不是直接声明组件,否则会导致组件的依赖(比如指令、服务)缺失,进而引发注入错误。
修改后的完整测试代码
// File: login.component.spec.ts import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; import { ButtonModule } from 'primeng/button'; import { DialogModule } from 'primeng/dialog'; // 导入PrimeNG的Dialog模块 import { AlertsService } from '../../global/alerts/alerts.service'; // 恢复导入 import { UserService } from '../../net-incident/services/user.service'; import { AuthService } from '../../net-incident/services/auth.service'; import { LoginComponent } from './login.component'; import { ServerSelectionWindowComponent } from '../../net-incident/server-selection-window/server-selection-window.component'; describe('LoginComponent', () => { let sut: LoginComponent; let fixture: ComponentFixture<LoginComponent>; let alertService: AlertsService; const authServiceSpy = jasmine.createSpyObj('AuthService', ['authenticate', 'logout', 'isLoggedIn', 'isLoggedOut']); const userServiceSpy = jasmine.createSpyObj('UserService', ['emptyUser', 'getUser', 'getUserServer']); beforeEach(async(() => { await TestBed.configureTestingModule({ imports: [ FormsModule, ButtonModule, DialogModule, // 替换手动声明的Dialog,用模块导入 BrowserAnimationsModule ], declarations: [ LoginComponent, ServerSelectionWindowComponent // 移除PrimeNG的组件声明 ], providers: [ AlertsService, // 可以直接用useClass的简写,或者保持{provide: ..., useClass: ...} { provide: AuthService, useValue: authServiceSpy }, { provide: UserService, useValue: userServiceSpy } // 把useClass改成useValue ] }).compileComponents(); // 链式调用compileComponents,更符合Angular 9的写法 alertService = TestBed.inject(AlertsService); // Angular 9推荐用inject代替get })); beforeEach(() => { fixture = TestBed.createComponent(LoginComponent); sut = fixture.componentInstance; fixture.detectChanges(); }); it('should be created ...', () => { expect(sut).toBeTruthy(); }); });
额外的优化点
- Angular 9中推荐使用
TestBed.inject()代替TestBed.get(),后者已经被废弃。 - 把
compileComponents()改成链式调用并添加await,确保组件编译完成后再执行后续逻辑,避免异步时序问题。
内容的提问来源于stack exchange,提问作者Phil Huhn
相关产品推荐
相关产品推荐

