You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:17:53