• [Angular & Unit Testing] Testing a RouterOutlet component


    The way to test router componet needs a little bit setup, first we need to create a "router-stubs.ts". This file is a helper file.

    // export for convenience.
    export { ActivatedRoute, Router, RouterLink, RouterOutlet} from '@angular/router';
    
    import { Component, Directive, Injectable, Input } from '@angular/core';
    import { NavigationExtras } from '@angular/router';
    
    @Directive({
      selector: '[routerLink]',
      host: {
        '(click)': 'onClick()'
      }
    })
    export class RouterLinkStubDirective {
      @Input('routerLink') linkParams: any;
      navigatedTo: any = null;
    
      onClick() {
        this.navigatedTo = this.linkParams;
      }
    }
    
    @Component({selector: 'router-outlet', template: ''})
    export class RouterOutletStubComponent { }
    
    @Injectable()
    export class RouterStub {
      navigate(commands: any[], extras?: NavigationExtras) { }
    }
    
    
    // Only implements params and part of snapshot.paramMap
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    import { convertToParamMap, ParamMap } from '@angular/router';
    
    @Injectable()
    export class ActivatedRouteStub {
    
      // ActivatedRoute.paramMap is Observable
      private subject = new BehaviorSubject(convertToParamMap(this.testParamMap));
      paramMap = this.subject.asObservable();
    
      // Test parameters
      private _testParamMap: ParamMap;
      get testParamMap() { return this._testParamMap; }
      set testParamMap(params: {}) {
        this._testParamMap = convertToParamMap(params);
        this.subject.next(this._testParamMap);
      }
    
      // ActivatedRoute.snapshot.paramMap
      get snapshot() {
        return { paramMap: this.testParamMap };
      }
    }
    
    
    /*
    Copyright 2017 Google Inc. All Rights Reserved.
    Use of this source code is governed by an MIT-style license that
    can be found in the LICENSE file at http://angular.io/license
    */

    The component we want to test:

    <app-banner></app-banner>
    <app-welcome></app-welcome>
    
    <nav>
      <a routerLink="/dashboard">Dashboard</a>
      <a routerLink="/heroes">Heroes</a>
      <a routerLink="/about">About</a>
    </nav>
    
    <router-outlet></router-outlet>
    import { Component } from '@angular/core';
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html'
    })
    export class AppComponent { }

    Testing setup:

    beforeEach( async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          BannerComponent, WelcomeStubComponent,
          RouterLinkStubDirective, RouterOutletStubComponent
        ]
      })
    
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(AppComponent);
        comp    = fixture.componentInstance;
      });
    }));

    We need to declare 'RouterLinkStubDirective' & 'RouterOutletStubComponent' which we created in stub helper file.

    beforeEach(() => {
      // trigger initial data binding
      fixture.detectChanges();
    
      // find DebugElements with an attached RouterLinkStubDirective
      linkDes = fixture.debugElement
        .queryAll(By.directive(RouterLinkStubDirective));
    
      // get the attached link directive instances using the DebugElement injectors
      links = linkDes
        .map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective);
    });

    Some tests:

    it('can get RouterLinks from template', () => {
      expect(links.length).toBe(3, 'should have 3 links');
      expect(links[0].linkParams).toBe('/dashboard', '1st link should go to Dashboard');
      expect(links[1].linkParams).toBe('/heroes', '1st link should go to Heroes');
    });
    
    it('can click Heroes link in template', () => {
      const heroesLinkDe = linkDes[1];
      const heroesLink = links[1];
    
      expect(heroesLink.navigatedTo).toBeNull('link should not have navigated yet');
    
      heroesLinkDe.triggerEventHandler('click', null);
      fixture.detectChanges();
    
      expect(heroesLink.navigatedTo).toBe('/heroes');
    });
  • 相关阅读:
    React 创建一个自动跟新时间的组件
    React 组件传值 父传递儿子
    React 以两种形式去创建组件 类或者函数(二)
    React 语法基础(一)之表达式和jsx
    ref的使用
    使用scale等比例缩放图片
    Vue动态加载图片图片不显示
    div里面的元素在【垂直 方向】上水平分布 使用calc()函数动态计算
    控制label标签的宽度,不让它换行 label标签左对齐
    表单验证
  • 原文地址:https://www.cnblogs.com/Answer1215/p/7656426.html
Copyright © 2020-2023  润新知