1

I'm trying to test if click event is properly handled. I'm trying to trigger click event on a button and check if proper call on router was executed. Don't know why stubRouteSpy did not registered call to navigate (last expect fails)

Template code:

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

Component code:

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

Spec code:

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 Answer 1

1

According the documentation here, you should get the provided RouterStub from the injector.

I suggest you use the example in the documentation.

the stub class:

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

provide:

{ provide: Router,      useClass: RouterStub }

get injector:

routerStub = fixture.debugElement.injector.get(RouterStub);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! This is exactly what I was doing wrong. After getting instance from injector test passed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.