簡體   English   中英

使用 Router.events 進行單元測試 Angular 9

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM