sti*_*rts 19 unit-testing mocking jasmine angular
在我的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;
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
目前我正在测试sub是否为null但我想测试100%覆盖率的函数.
我想模拟路由器对象,以便我可以模拟URL,然后测试是否正确设置了this.loggedIn.
我将如何进行模拟此功能?我尝试了但是我不知道如何通过涉及的回调和NavigationEnd来实现这一点.
sti*_*rts 24
我找到了答案,如果有人正在寻找它:
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();
});
}
Run Code Online (Sandbox Code Playgroud)
For*_*man 11
我从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);
}
}
Run Code Online (Sandbox Code Playgroud)
接受的答案是正确的,但这有点简单,你可以更换
public ne = new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login');
public events = new Observable(observer => {
observer.next(this.ne);
observer.complete();
});
Run Code Online (Sandbox Code Playgroud)
通过:
public events = Observable.of( new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login'));
Run Code Online (Sandbox Code Playgroud)
并在下面找到一个完整的测试文件来测试问题中的函数:
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);
});
});
Run Code Online (Sandbox Code Playgroud)
小智 6
这是一个非常古老的问题,但我只是在寻找比我现有的更好的东西时遇到它,就我而言,我需要测试几个不同的事件。我的基本方法是将 Router.events 更改为非只读值,例如
(router as any).events = new BehaviorSubject<any>(null);
fixture.detectChanges();
router.events.next(new NavigationEnd(0, 'http://localhost:4200/login',
'http://localhost:4200/login'));
expect(comp.loggedIn).toEqual(true);
Run Code Online (Sandbox Code Playgroud)
希望这对某人有帮助。环顾四周后我找不到更简单的解决方案
ReplaySubject<RouterEvent>
嘲笑router.events
filter
而不是instanceof
import {Injectable} from '@angular/core';
import {NavigationEnd, Router, RouterEvent} from '@angular/router';
import {filter, map} from 'rxjs/operators';
import {Observable} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class RouteEventService {
constructor(private router: Router) {
}
subscribeToRouterEventUrl(): Observable<string> {
return this.router.events
.pipe(
filter(event => event instanceof NavigationEnd),
map((event: RouterEvent) => event.url)
);
}
}
Run Code Online (Sandbox Code Playgroud)
import {TestBed} from '@angular/core/testing';
import {RouteEventService} from './route-event.service';
import {NavigationEnd, NavigationStart, Router, RouterEvent} from '@angular/router';
import {Observable, ReplaySubject} from 'rxjs';
describe('RouteEventService', () => {
let service: RouteEventService;
let routerEventReplaySubject: ReplaySubject<RouterEvent>;
let routerMock;
beforeEach(() => {
routerEventReplaySubject = new ReplaySubject<RouterEvent>(1);
routerMock = {
events: routerEventReplaySubject.asObservable()
};
TestBed.configureTestingModule({
providers: [
{provide: Router, useValue: routerMock}
]
});
service = TestBed.inject(RouteEventService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
describe('subscribeToEventUrl should return route equals to mock url on firing', () => {
it('NavigationEnd', () => {
const result: Observable<string> = service.subscribeToRouterEventUrl();
const url = '/mock';
result.subscribe((route: string) => {
expect(route).toEqual(url);
});
routerEventReplaySubject.next(new NavigationEnd(1, url, 'redirectUrl'));
});
it('NavigationStart', () => {
const result: Observable<string> = service.subscribeToRouterEventUrl();
const url = '/mock';
result.subscribe((route: string) => {
expect(route).toBeNull();
});
routerEventReplaySubject.next(new NavigationStart(1, url, 'imperative', null));
});
});
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15331 次 |
最近记录: |