[英]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.