[英]Unit Testing with Router.events Angular 9
我是 Angular 和一般單元測試的新手,現在我找不到在下面的此服務中測試代碼的方法。 這負責創建面包屑菜單。 在路由模塊中,我為每個路由添加了 --> data:{breadcrumb:'custom name'}。
這是服務代碼:
import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {IBreadcrumbs} from '../breadcrumb/ibreadcrumbs';
import {ActivatedRouteSnapshot, Data, NavigationEnd, Router} from '@angular/router';
import {filter} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class BreadcrumbService {
/// Subject emitting the breadcrumb hierarchy
private readonly breadcrumbsSub$ = new BehaviorSubject<IBreadcrumbs[]>([]);
// Observable exposing the breadcrumb hierarchy
readonly breadcrumbs$ = this.breadcrumbsSub$.asObservable();
constructor(private router: Router) {
this.router.events
.pipe(
// Filter the NavigationEnd events as the breadcrumb is updated only when the route reaches its end
filter((event) => event instanceof NavigationEnd)
)
.subscribe((event) => {
// Construct the breadcrumb hierarchy
const root = this.router.routerState.snapshot.root;
const breadcrumbs: IBreadcrumbs[] = [];
this.addBreadcrumb(root, breadcrumbs);
// Emit the new hierarchy
this.breadcrumbsSub$.next(breadcrumbs);
});
}
private addBreadcrumb(
route: ActivatedRouteSnapshot | null,
breadcrumbs: IBreadcrumbs[]
) {
if (route) {
// Add an element for the current route part
if (route.data.breadcrumb) {
const breadcrumb = {
label: this.getLabel(route.data),
url: route.url.toString()
};
breadcrumbs.push(breadcrumb);
}
// Add another element for the next route part
this.addBreadcrumb(route.firstChild, breadcrumbs);
}
}
private getLabel(data: Data) {
// The breadcrumb can be defined as a static string or as a function to construct the breadcrumb element out of the route data
return typeof data.breadcrumb === 'function'
? data.breadcrumb(data)
: data.breadcrumb;
}
}
這是我的 spec.ts 文件
import {TestBed} from '@angular/core/testing';
import {BreadcrumbService} from './breadcrumb.service';
import {RouterTestingModule} from '@angular/router/testing';
import {Router, RouterEvent} from '@angular/router';
import {ReplaySubject} from 'rxjs';
fdescribe('BreadcrumbService', () => {
let service: BreadcrumbService;
let routerEventRelaySubject: ReplaySubject<RouterEvent>;
let routerMock;
let router: Router;
beforeEach(() => {
routerEventRelaySubject = new ReplaySubject<RouterEvent>(1);
routerMock = {
events: routerEventRelaySubject.asObservable()
};
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [{provide: Router, useValue: routerMock}]
});
service = TestBed.inject(BreadcrumbService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
我需要至少 80% 的覆蓋率,請幫助我實現這一目標。 先感謝您。
如果您想了解如何在 Angular 中測試路由,這里有一篇很好的文章: 使用 RouterTestingModule 測試 Angular 路由組件。 我預見的唯一警告是this.router.routerState.snapshot
的使用。 RouterTestingModule
可能不會評估它。 您可能需要像處理events
一樣模擬它。
我想提供一個完整的解決方案太令人期待了。 因此,理解這篇文章並自己動手將是 go 的好方法。
請在發布問題之前展示您之前的嘗試。 如果您不熟悉單元測試,那么對空的BreadcrumbService
進行測試可能會有所幫助。 然后,您可以為構造函數添加另一個測試。 由於您同時使用 Angular 路由器和 rxjs 運算符,因此查看他們的文檔以了解如何在其框架中進行模擬/測試會很有用。
底線:做一個簡單的小測試,通過,添加功能,然后重復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.