简体   繁体   English

使用 Router.events 进行单元测试 Angular 9

[英]Unit Testing with Router.events Angular 9

I am new to Angular and to unit testing in general and now I can't find a way to test the code in this service below.我是 Angular 和一般单元测试的新手,现在我找不到在下面的此服务中测试代码的方法。 This is responsable for the creation of a breadcrumb menu.这负责创建面包屑菜单。 In the Routing Module I have added for every route --> data:{breadcrumb:'custom name'}.在路由模块中,我为每个路由添加了 --> data:{breadcrumb:'custom name'}。

Here is the service code:这是服务代码:

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;
  }


}

And here is my spec.ts file这是我的 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();
  });

});

I need a coverage of 80% minimum, please help me achieve this.我需要至少 80% 的覆盖率,请帮助我实现这一目标。 Thank you in advance.先感谢您。

If you want to build an understanding of how to test routing in Angular here is a good article: Testing Angular routing components with the RouterTestingModule .如果您想了解如何在 Angular 中测试路由,这里有一篇很好的文章: 使用 RouterTestingModule 测试 Angular 路由组件 The only caveat I foresee is the usage of the this.router.routerState.snapshot .我预见的唯一警告是this.router.routerState.snapshot的使用。 It might be not evaluated by the RouterTestingModule . RouterTestingModule可能不会评估它。 You might need to mock it the same way as you do with events .您可能需要像处理events一样模拟它。

I suppose providing a full solution would be too much to expect.我想提供一个完整的解决方案太令人期待了。 So, comprehending the article and do it yourself would be a nice way to go.因此,理解这篇文章并自己动手将是 go 的好方法。

Please show your previous attempts before posting a question.请在发布问题之前展示您之前的尝试。 If you're new to unit testing, it might be helpful if you do a test of an empty BreadcrumbService .如果您不熟悉单元测试,那么对空的BreadcrumbService进行测试可能会有所帮助。 Then, you can add another test for the constructor.然后,您可以为构造函数添加另一个测试。 Since you're using both Angular router and rxjs operators, it would be useful to look into their documentation to see how to mock/test in their framework.由于您同时使用 Angular 路由器和 rxjs 运算符,因此查看他们的文档以了解如何在其框架中进行模拟/测试会很有用。

Bottom line: do a small simple test that passes, add functionality, and repeat.底线:做一个简单的小测试,通过,添加功能,然后重复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM