私のapp.component.tsには、次のngOnInit関数があります。
ngOnInit() {
this.sub = this.router.events.subscribe(e => {
if (e instanceof NavigationEnd) {
if (!e.url.includes('login')) {
this.loggedIn = true;
} else {
this.loggedIn = false;
}
}
});
}
現在、subがnullでないかどうかをテストしていますが、100%のカバレッジで関数をテストしたいです。
ルーターオブジェクトをモックして、URLをシミュレートし、this.loggedInが正しく設定されているかどうかをテストできるようにします。
この機能をどのようにモックするのですか?私はそれを試しましたが、関連するコールバックとNavigationEndでこれをどのように行うかわかりません。
誰かがそれを探しているなら、私は答えを見つけました:
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();
});
}
Angular docsからこのメソッドを使用してテスト用のNavigationEndイベントを実装するルータースタブのバージョンを作成しました。
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);
}
}
受け入れられた答えは正しいですが、これは少し簡単です、あなたは置き換えることができます
public ne = new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login');
public events = new Observable(observer => {
observer.next(this.ne);
observer.complete();
});
沿って:
public events = Observable.of( new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login'));
そして、問題の機能をテストするための完全なテストファイルを以下で見つけます。
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);
});
});
前の例public events = Observable.of( new NavigationEnd(0, 'http://localhost..'));
は、が文句を言うKarmaに従って機能していないようです:
失敗:undefinedはオブジェクトではありません(「router.routerState.root」を評価)rootRoute @ http:// localhost:9876/_karma_webpack_/vendor.bundle.js
(モックされた)ルーターインスタンスeventsにもかかわらず、元のapp.component.tsのngOninit()
でサブスクリプションコールバックが正常に実行されています。 Karmaがテスト中のアプリケーションコンポーネント:
_this.sub = this.router.events.subscribe(e => { // successful execution across Karma
_
実際、Routerがモックされた方法は不完全に見え、Karmaの将来のstructureとして不正確に見えます:実行時に未定義になる_router.routerState
_のため。
AngularルータはRoutesRecognized
eventsを含む私の側で正確に「スタブ」されています) 私の場合はObservable
sとして人工的に焼きます:
_class MockRouter {
public events = Observable.of(new RoutesRecognized(2 , '/', '/',
createRouterStateSnapshot()));
}
const createRouterStateSnapshot = function () {
const routerStateSnapshot = jasmine.createSpyObj('RouterStateSnapshot',
['toString', 'root']);
routerStateSnapshot.root = jasmine.createSpyObj('root', ['firstChild']);
routerStateSnapshot.root.firstChild.data = {
xxx: false
};
return <RouterStateSnapshot>routerStateSnapshot;
};
_
ngOnInit()
bodyが期待するものに合うように、深い構造を持つRoutesRecognized
eventが必要です:
_ngOnInit() {
this.router.events.filter((event) => {
return event instanceof RoutesRecognized;
}).subscribe((event: RoutesRecognized) => {
// if (!event.state.root.firstChild.data.xxx) {
// RoutesRecognized event... to be baked from specs mocking strategy
});
}
_
<package.json>コンテンツの要約/要約:
アンギュラー/ルーター:5.2.9、カルマ:2.0.2、ジャスミンコア:2.6.4、カルマジャスミン:1.1.2