Angular2触发按钮点击单元测试和验证事件处理

Angular2 trigger button click in unit test and verify event handling

我正在尝试测试是否正确处理了点击事件。我正在尝试触发按钮上的点击事件并检查是否执行了对路由器的正确调用。 不知道为什么 stubRouteSpy 没有注册导航调用(最后期望失败)

模板代码:

<div class="col-lg-3 col-md-4 col-xs-6 thumb project" *ngFor="let project of projects">
    <div class = "thumbnail">
        <img class="img-responsive img-rounded" src="{{project.imgUrl}}" alt="">
        <div class = "caption">
         <h4 id='titleHeader'>{{project.title}}</h4>
         <div class="btn-group" role="group" style="all">
          <button class="btn btn-primary">Order</button>
          <button id='customizeButton' class="btn btn-info" (click)="onCustomize(project.id)">Customize</button>
        </div>
    </div>
</div>

组件代码:

public errorMessage = '';
public projects = [];

constructor(private router: Router, private projectListService: ProjectListService) {
}

public ngOnInit() {
    this.getProjects();
}

public getProjects() {
    this.projectListService.getAllProjects()
        .subscribe(
            (projects) => this.projects = projects,
            (error) =>  this.errorMessage = <any> error);
}

public onCustomize(id: string) {
    console.log(id);
    let navigate = this.router.navigate(['design', id]);
}

规格代码:

describe('GalleryComponent (inline template)', () => {

    let comp: GalleryComponent;
    let fixture: ComponentFixture<GalleryComponent>;
    let projectListService: ProjectListService;
    let spy: jasmine.Spy;
    let de: DebugElement[];
    let stubRoute: Router;
    let stubRouteSpy: jasmine.Spy;

    beforeEach(() => {
        stubRoute = <Router> { navigate: ([]) => {}};
        TestBed.configureTestingModule({
            declarations: [GalleryComponent],
            providers: [
                ProjectListService,
                {provide: Router, useValue: stubRoute},
                {provide: Http, useValue: {}}
                ],
        });

        fixture = TestBed.createComponent(GalleryComponent);
        comp = fixture.componentInstance;

        // ProjectListService actually injected into the component
        projectListService = fixture.debugElement.injector.get(ProjectListService);

        // Setup spy on the `getAllProjects` method
        let fakeProjects = [new Project(1, 'title1', ''), new Project(2, 'title2', '')];
        spy = spyOn(projectListService, 'getAllProjects')
            .and.returnValue(Observable.of<Project[]>(fakeProjects));

        stubRouteSpy = spyOn(stubRoute, 'navigate');
    });

    it('should navigate to designer when customize button clicked', async(() => {
        fixture.detectChanges(); // init
        fixture.whenStable().then(() => { // wait for async getAllProjects
            fixture.detectChanges(); // update view with projects

            fixture.nativeElement.querySelectorAll('#customizeButton')[0].click();
            expect(fixture.nativeElement.querySelectorAll('#customizeButton').length).toBe(2); // this pass

            fixture.detectChanges();

            expect(stubRouteSpy.calls.any()).toBe(true, 'navigate called'); // this is false
        });
    }));
});

根据文档here,您应该从注入器中获取提供的 RouterStub。

我建议您使用文档中的示例。

存根 class:

class RouterStub {
    navigateByUrl(url: string) { return url; }
}

提供:

{ provide: Router,      useClass: RouterStub }

获取注射器:

routerStub = fixture.debugElement.injector.get(RouterStub);