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

Angular 4单元测试注入Router模块报错:ReferenceError: Router未定义

解决Angular 4单元测试中inject注入Router时的ReferenceError问题

我来帮你排查这个问题,从你的代码和堆栈信息来看,主要有几个明显的问题导致了这个错误,咱们一步步来修复:

问题分析

  • 未定义的getVendorsDataStub:你在TestBed的providers里配置了DriverService使用getVendorsDataStub,但这个变量根本没有定义,这会直接导致TestBed初始化失败,破坏整个依赖注入环境,进而让inject无法正确获取Router实例。
  • inject回调的依赖解析问题:虽然你导入了Router,但如果TestBed的配置失败,inject函数无法正确解析依赖,就会抛出类似的未定义错误。另外你在it块里才初始化fixture和component,也不符合单元测试的最佳实践。
  • 多余的语法闭合符:你的describe块最后多了一个),这会导致语法错误,影响测试代码的正常执行。

修正后的测试代码

import { TestBed, async, inject, fakeAsync, tick, ComponentFixture, getTestBed } from '@angular/core/testing';
import { RouterTestingModule } from "@angular/router/testing";
import { Router } from "@angular/router";
import { Location } from "@angular/common";
import { DriversModule } from '../../drivers.module';
import { DriverAddComponent } from './driver.add.component';
import { routes, routing } from '../../drivers.routing';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs/Observable';
import { DriverService } from '../../services/driver.service';

// 先定义DriverService的Stub类,替换未定义的getVendorsDataStub
class DriverServiceStub {
  // 根据DriverService的实际方法补充Stub实现
  // 示例:如果有获取供应商的方法
  // getVendors() {
  //   return Observable.of([]);
  // }
}

describe('Add driver Component', () => {
  let component: DriverAddComponent;
  let fixture: ComponentFixture<DriverAddComponent>;
  let routerMock;
  let router: Router;
  let location: Location;

  beforeEach(async(() => {
    routerMock = { navigate: jasmine.createSpy('navigate') };

    TestBed.configureTestingModule({
      imports: [
        DriversModule,
        RouterTestingModule.withRoutes(routes)
      ],
      providers: [
        { provide: Router, useValue: routerMock },
        { provide: DriverService, useClass: DriverServiceStub } // 使用定义好的Stub类
      ],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }));

  // 在beforeEach中统一初始化组件和依赖,避免重复代码
  beforeEach(() => {
    fixture = TestBed.createComponent(DriverAddComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router); // 直接从TestBed获取Router实例,无需inject
    location = TestBed.get(Location);
  });

  it('should navigate to the add a new driver page', () => {
    component.goBack();
    expect(router.navigate).toHaveBeenCalledWith(['/addDriver']);
    
    // 额外:如果想验证实际导航路径,可使用fakeAsync配合Location测试
    // fakeAsync(() => {
    //   component.goBack();
    //   tick();
    //   expect(location.path()).toBe('/addDriver');
    // })
  });
});

关键修改点说明

  1. 补充DriverServiceStub:必须提供有效的DriverService替代类,否则TestBed无法完成初始化,依赖注入系统会直接崩溃,你需要根据实际业务方法补充Stub的具体实现。
  2. 提前初始化组件实例:在beforeEach里完成组件和依赖的初始化,确保每个测试用例都能拿到干净的组件实例,同时减少重复代码。
  3. 改用TestBed.get获取依赖:相比inject函数,直接通过TestBed.get(Router)获取实例更直观,也能避免inject相关的作用域问题。
  4. 修复语法错误:去掉了describe块末尾多余的闭合括号,确保代码语法完全正确。

额外建议

如果你还是想使用inject函数,一定要确保TestBed配置完全正确,且代码没有语法错误。另外Angular 4的测试推荐使用TestBed.get来获取依赖,这是更简洁且不易出错的方式。

内容的提问来源于stack exchange,提问作者Harish98

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:01:42