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

时间:2017-03-10 15:12:28

标签: unit-testing angular jasmine spy

我试图测试点击事件是否得到妥善处理。我尝试触发按钮上的点击事件,并检查路由器上是否执行了正确的呼叫。 不知道为什么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
        });
    }));
});

1 个答案:

答案 0 :(得分:1)

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

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

存根类:

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

提供:

{ provide: Router,      useClass: RouterStub }

获取注射器:

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