angular 6测试脚本中的listenglobal渲染器事件触发

Posted

技术标签:

【中文标题】angular 6测试脚本中的listenglobal渲染器事件触发【英文标题】:listenglobal renderer event trigger in angular 6 testing script 【发布时间】:2019-03-01 21:53:34 【问题描述】:

我想测试我的 RolesComponent 的 listenGlobal Renderer 方法。 RolesComponent 代码如下。

import  Component, OnInit, Renderer, AfterViewInit  from '@angular/core';
import  Router  from '@angular/router';

import  AhanaService  from '../../services/ahana.service';

@Component(
    selector: 'app-roles',
    template: '<div><button roleId="1">test click</button></div>',
    styleUrls: ['./roles.component.css']
)
export class RolesComponent implements AfterViewInit 

    constructor(public router: Router, private ahanaService: AhanaService, private renderer: Renderer) 

    ngAfterViewInit(): void 
        this.renderer.listenGlobal('document', 'click', (event) => 
            if (event.target.hasAttribute("roleId")) 
                var roleId = event.target.getAttribute('roleId')
                // console.log('/configuration/update-role/' + roleId)
                this.router.navigate(['/configuration/update-role/' + roleId]);
            
        );
    


如何转换 RolesComponent.spec.ts 和 ngAfterViewInit(): void this.renderer.listenGlobal('document', 'click', (event) =&gt; 方法调用。

【问题讨论】:

【参考方案1】:

如果您想测试您的点击侦听器的行为是否符合预期,那么您可以从您的测试中手动调用 ngAfterViewInit 生命周期挂钩,并断言 router.navigate() 被按预期调用。为了做到这一点,您可以模拟和监视 router.navigate 方法,并期望它已使用特定的 url 路由调用。结果与this stack overflow answer 非常相似。

import  async, ComponentFixture, fakeAsync, TestBed, tick  from '@angular/core/testing';
import  Router  from '@angular/router';
import  RolesComponent  from './roles.component';

describe('RolesComponent', () => 
  let component: RolesComponent;
  let fixture: ComponentFixture<RolesComponent>;
  const routerSpy =  navigate: jasmine.createSpy('navigate') ; // Create our router mock, which we will spy on

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      declarations: [ RolesComponent ],
      providers: [ provide: Router, useValue: routerSpy ], // Register our mock router as a provider
    )
    .compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(RolesComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  );

  it('should register click listener', fakeAsync(() => 
    component.ngAfterViewInit(); // Call the lifecycle hook
    const button = fixture.debugElement.nativeElement.querySelector('button');
    button.click(); // "Click" the button
    tick();
    expect(routerSpy.navigate).toHaveBeenCalledWith(['/configuration/update-role/1']); // Assert that our mock was called
  ));
);

【讨论】:

listenGlobal 方法调用在哪里? 在您传递给listenGlobal 的回调中有一个router.navigate 调用。如果没有更多上下文,这似乎是您想要在此处测试的功能,因为这会将用户踢到更新角色页面。

以上是关于angular 6测试脚本中的listenglobal渲染器事件触发的主要内容,如果未能解决你的问题,请参考以下文章

如何关闭 Angular 6 ng 测试的源映射?

Angular 2/4/6/7 - 使用路由器进行单元测试

如何在节点脚本中重用 Angular 6 API 服务?

Angular 6 - 在组件级别添加脚本并检查它是不是存在

使用 GET 从 Angular 6 到 Google Apps 脚本的 CORS 问题

Angular 6 - 集成 jQuery/JavaScript 文件