2016-07-20 21 views
8

Trong app.component.ts của tôi, tôi có chức năng ngOnInit sau:router.events.subscribe Mocking() 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; 
     } 
     } 
    }); 
    } 

Hiện nay tôi đang thử nghiệm nếu phụ không phải là null nhưng tôi muốn thử nghiệm chức năng với mức độ phù hợp 100%.

Tôi muốn giả lập đối tượng bộ định tuyến để tôi có thể mô phỏng URL và sau đó kiểm tra xem this.loggedIn có được đặt chính xác hay không.

Tôi sẽ tiến hành thử chức năng này như thế nào? Tôi đã thử nó nhưng tôi không biết làm thế nào tôi sẽ thực hiện việc này với các cuộc gọi lại có liên quan và với NavigationEnd.

Trả lời

16

Tôi đã tìm thấy câu trả lời, nếu ai đó đang tìm kiếm nó:

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

Cảm ơn để chia sẻ giải pháp này. Đã cứu tôi rất nhiều công việc. Uwe – Uwe

+5

Bạn có thể hiển thị tệp thử nghiệm đầy đủ không? –

+0

Vui lòng cung cấp thông tin về Cấu hình TestingModule của bạn. –

7

Tôi tạo ra một phiên bản của stub router từ docs góc có sử dụng phương pháp này để thực hiện các sự kiện NavigationEnd để thử nghiệm:

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

Bạn có bất kỳ đầu mối nào để giả lập 'RoutesRecognized' thay vì' NavigationEnd' không? – DAG

0

Câu trả lời được chấp nhận là đúng nhưng đây là một chút đơn giản hơn, bạn có thể thay

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

bởi:

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

Và tìm thấy bên dưới một tập tin thử nghiệm đầy đủ để kiểm tra các chức năng trong câu hỏi:

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

});