Angular路由测试报错:getBaseHref未定义及base href未设置问题
解决Angular路由测试中的
getBaseHref和No base href set错误 我来帮你搞定这两个路由测试的问题,咱们一步步拆解原因和解决方案:
第一个错误:TypeError: this._platformStrategy.getBaseHref is not a function
你最初的测试配置里踩了几个坑:
- 在
providers里错误地加入了HttpModule和ConnectionBackend——这些模块应该放在imports数组里,而非providers。 - 同时手动注册了
Location和LocationStrategy,导致依赖注入冲突,Location实例的_platformStrategy没有被正确初始化,调用getBaseHref时自然报错。 - 其实
RouterTestingModule已经默认提供了Location的测试实现,根本不需要手动在providers里添加。
第二个错误:Error: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.
当你改用PathLocationStrategy时,Angular必须知道应用的基础路径(base href)。你之前移除了APP_BASE_HREF的配置,而测试环境的文档里又没有<base>标签,所以触发了这个错误。
修复后的完整测试代码
下面是调整后的测试脚本,我标注了关键修改点:
import { fakeAsync, tick } from '@angular/core/testing'; import { Router, RouterTestingModule } from '@angular/router'; import { Location, LocationStrategy, PathLocationStrategy } from '@angular/common'; import { TestBed } from '@angular/core/testing'; import { APP_BASE_HREF } from '@angular/common'; // 导入你的组件和服务 import { MainComponent } from './main.component'; import { AlarmsTableComponent } from './alarms-table.component'; import { AddAlarmsFormComponent } from './add-alarms-form.component'; import { EditAlarmsFormComponent } from './edit-alarms-form.component'; import { LoginComponent } from './login.component'; import { DataFilterPipe } from './data-filter.pipe'; import { AuthService } from './auth.service'; import { AlarmsService } from './alarms.service'; import { DataTableModule } from 'angular-datatables'; import { ReactiveFormsModule, FormsModule } from '@angular/forms'; import { HttpClientTestingModule } from '@angular/common/http/testing'; describe('Router: App', () => { let location: Location; let router: Router; let fixture; beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AlarmsTableComponent, AddAlarmsFormComponent, EditAlarmsFormComponent, LoginComponent, DataFilterPipe ], imports: [ // 推荐显式传入你的应用路由配置,保证测试行为和真实应用一致 RouterTestingModule.withRoutes([ // 这里替换成你的实际路由规则,比如: // { path: 'page', component: AlarmsTableComponent }, // { path: '', redirectTo: '/page', pathMatch: 'full' } ]), DataTableModule, ReactiveFormsModule, FormsModule, HttpClientTestingModule // 移除了冗余的HttpModule ], providers: [ AuthService, AlarmsService, DataFilterPipe, // 提供和应用一致的基础路径 { provide: APP_BASE_HREF, useValue: '/page' }, // 指定使用PathLocationStrategy { provide: LocationStrategy, useClass: PathLocationStrategy } ], }); // 用inject代替get,Angular 9+推荐的类型安全依赖获取方式 router = TestBed.inject(Router); location = TestBed.inject(Location); fixture = TestBed.createComponent(MainComponent); router.initialNavigation(); }); it('navigate to empty path redirects to /page', fakeAsync(() => { // 匹配路由配置的逻辑:空路径重定向到/page router.navigate(['']); tick(); expect(location.path()).toBe('/page'); })); });
额外的注意事项
- 路由配置要匹配:一定要用
RouterTestingModule.withRoutes()传入你的实际路由规则,否则测试的路由行为会和真实应用脱节。 - 清理冗余模块:
HttpClientTestingModule已经包含了测试HTTP请求所需的工具,不需要再导入旧的HttpModule。 - 测试用例要准确:如果你的路由是“空路径重定向到/page”,测试时应该调用
router.navigate(['']),而不是router.navigate(['page'])——后者会导航到/page/page(当base href为/page时),这大概率不是你想要的结果。 - 用
inject替代get:这是Angular新版本推荐的方式,类型更安全,避免潜在的类型错误。
内容的提问来源于stack exchange,提问作者user9699663
相关产品推荐
相关产品推荐

