2016-07-20 18 views
8

W moich app.component.ts Mam następującą funkcję ngOnInit:Mocking router.events.subscribe() Angular2

ngOnInit() { 
    this.sub = this.router.events.subscribe(e => { 
     if (e instanceof NavigationEnd) { 
     if (!e.url.includes('login')) { 
      this.loggedIn = true; 
     } else { 
      this.loggedIn = false; 
     } 
     } 
    }); 
    } 

Obecnie jestem testowania czy sub nie jest zerowa, ale chcę przetestować funkcja ze 100% pokryciem.

Chcę sfałszować obiekt routera, aby móc zasymulować adres URL, a następnie przetestować poprawność ustawienia this.loggedIn.

W jaki sposób mogę przystąpić do wyśmiewania tej funkcji? Próbowałem, ale nie wiem, jak bym to zrobił z zaangażowanym callbackiem i z NavigationEnd.

Odpowiedz

16

znalazłem odpowiedź, jeśli ktoś patrzy na niego:

import { 
    addProviders, 
    async, 
    inject, 
    TestComponentBuilder, 
    ComponentFixture, 
    fakeAsync, 
    tick 
} from '@angular/core/testing'; 
import { AppComponent } from './app.component'; 
import { Router, ROUTER_DIRECTIVES, NavigationEnd } from '@angular/router'; 
import { HTTP_PROVIDERS } from '@angular/http'; 
import { LocalStorage, WEB_STORAGE_PROVIDERS } from 'h5webstorage'; 
import { NavComponent } from '../nav/nav.component'; 
import { FooterComponent } from '../footer/footer.component'; 
import { Observable } from 'rxjs/Observable'; 

class MockRouter { 
    public ne = new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login'); 
    public events = new Observable(observer => { 
    observer.next(this.ne); 
    observer.complete(); 
    }); 
} 

class MockRouterNoLogin { 
    public ne = new NavigationEnd(0, 'http://localhost:4200/dashboard', 'http://localhost:4200/dashboard'); 
    public events = new Observable(observer => { 
    observer.next(this.ne); 
    observer.complete(); 
    }); 
} 
+0

Dzięki za udostępnienie tego rozwiązania. Zaoszczędził mi dużo pracy. Uwe – Uwe

+5

Czy możesz pokazać pełny plik testowy? –

+0

Proszę podać informacje na temat konfiguracji TestingModule. –

7

stworzyłem wersję odgałęzienie rutera od kątowe docs, która korzysta z tej metody do wdrożenia zdarzenie NavigationEnd do testowania:

import {Injectable} from '@angular/core'; 
 
import { NavigationEnd } from '@angular/router'; 
 
import {Subject} from "rxjs"; 
 

 
@Injectable() 
 
export class RouterStub { 
 
    public url; 
 
    private subject = new Subject(); 
 
    public events = this.subject.asObservable(); 
 

 
    navigate(url: string) { 
 
    this.url = url; 
 
    this.triggerNavEvents(url); 
 
    } 
 

 
    triggerNavEvents(url) { 
 
    let ne = new NavigationEnd(0, url, null); 
 
    this.subject.next(ne); 
 
    } 
 
}

+0

Czy masz pojęcie, jak wyśmiewać 'RoutesRecognized' zamiast' NavigationEnd'? – DAG

0

Zaakceptowanych odpowiedź jest poprawna, ale to jest nieco prostsze, można zastąpić

public ne = new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login'); 
    public events = new Observable(observer => { 
    observer.next(this.ne); 
    observer.complete(); 
    }); 

przez:

public events = Observable.of(new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login')); 

i znaleźć poniżej pełnego pliku testowego, aby przetestować funkcję w pytaniu:

import { NO_ERRORS_SCHEMA } from '@angular/core'; 
import { 
    async, 
    TestBed, 
    ComponentFixture 
} from '@angular/core/testing'; 

/** 
* Load the implementations that should be tested 
*/ 
import { AppComponent } from './app.component'; 

import { NavigationEnd, Router } from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 


class MockServices { 
    // Router 
    public events = Observable.of(new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login')); 
} 

describe(`App`,() => { 
    let comp: AppComponent; 
    let fixture: ComponentFixture<AppComponent>; 
    let router: Router; 

    /** 
    * async beforeEach 
    */ 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ AppComponent ], 
     schemas: [NO_ERRORS_SCHEMA], 
     providers: [ 
     { provide: Router, useClass: MockServices }, 
     ] 
    }) 
    /** 
    * Compile template and css 
    */ 
    .compileComponents(); 
    })); 

    /** 
    * Synchronous beforeEach 
    */ 
    beforeEach(() => { 
    fixture = TestBed.createComponent(AppComponent); 
    comp = fixture.componentInstance; 

    router = fixture.debugElement.injector.get(Router); 

    /** 
    * Trigger initial data binding 
    */ 
    fixture.detectChanges(); 
    }); 

    it(`should be readly initialized`,() => { 
    expect(fixture).toBeDefined(); 
    expect(comp).toBeDefined(); 
    }); 

    it('ngOnInit() - test that this.loggedIn is initialised correctly',() => { 
    expect(comp.loggedIn).toEqual(true); 
    }); 

});