[英]Angular 6 - how to mock router.events url response in unit test
[英]Angular Unit test router.events
我有一个组件可以更新特定路由器事件的变量。 我如何进行单元测试以确保下面的代码正常工作?
router.events.subscribe(event => {
if (event instanceof NavigationStart) {
this.isLoading = true;
} else if (event instanceof NavigationEnd || event instanceof NavigationCancel) {
this.isLoading = false;
} else if (event instanceof NavigationError) {
this.isLoading = false;
// console.error('effect error: ', error);
}
});
路由器存根
class MockRouter {
navigate = jasmine.createSpy('navigate');
start = new NavigationStart(0, '/home');
end = new NavigationEnd(1, '/home', '/dashboard');
events = new Observable(observer => {
observer.next(this.start);
observer.next(this.end);
observer.complete();
});
}
我遇到了类似的情况,这就是我想出来的:
describe('router.events', () => {
const mockStart = of(new NavigationStart(0, '/testUrl'));
const mockEnd = of(new NavigationEnd(0, '/testUrl', '/testUrlRedirect'));
const mockCancel = of(new NavigationCancel(0, '/testUrl', '/testReason'));
const mockError = of(new NavigationError(0, '/testUrl', 'test error'));
let routerEventSpy: jasmine.Spy;
beforeEach(() => {
routerEventSpy = spyOn(component.router, 'events');
});
it('should set isLoading to true', () => {
// Arrange
routerEventSpy.and.returnValue(mockStart);
component.isLoading = false; // initial value to make sure code is effective
// Act
// Call whatever method contains your router.events.subscribe - for example:
component.ngOnInit(); // <-- Just an example, you should replace this with your corresponding method
// Assert
expect(component.isLoading).toBe(true);
});
it('should set isLoading to false for NavigationEnd', () => {
// Arrange
routerEventSpy.and.returnValue(mockEnd);
component.isLoading = true; // initial value, see first test
// Act
// Call whatever method contains your router.events.subscribe - for example:
component.ngOnInit(); // <-- Just an example, see first test
// Assert
expect(component.isLoading).toBe(false);
});
it('should set isLoading to false for NavigationCancel', () => {
// Arrange
routerEventSpy.and.returnValue(mockCancel);
component.isLoading = true; // initial value, see first test
// Act
// Call whatever method contains your router.events.subscribe - for example:
component.ngOnInit(); // <-- Just an example, see first test
// Assert
expect(component.isLoading).toBe(false);
});
it('should set isLoading to false for NavigationError', () => {
// Arrange
routerEventSpy.and.returnValue(mockError);
component.isLoading = true; // initial value, see first test
// Act
// Call whatever method contains your router.events.subscribe - for example:
component.ngOnInit(); // <-- Just an example, see first test
// Assert
expect(component.isLoading).toBe(false);
});
});
一些注意事项:
component
应该替换为您存储fixture.componentInstance
任何内容。这是您测试中的this
。Observable
的-和它的方法,您已经声明spy
正在恢复of
观测来触发subscribe
。 可能有一种方法可以将路由器存根用于您的目的(例如isLoading
的回答),但您的问题只要求一种测试该逻辑和isLoading
变量的方法。protected
或private
(一个很好的做法),您仍然可以使用括号表示法对其进行监视 - 例如spyOn(component['router'], 'events')
。您需要创建一个简单的路由器存根以允许在测试期间发出各种路由器事件。
路由器存根:
// mocked source of events
const routerEventsSubject = new Subject<RouterEvent>();
const routerStub = {
events: routerEventsSubject.asObservable()
};
describe('FooComponent', () => {
...
然后您只需使用该存根:
...
let router: Router;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: Router,
useValue: routerStub
}
]
});
router = TestBed.inject(Router);
...
测试如下所示:
it('should be loading on a navigation start', () => {
// create a navigation event
routerEventsSubject.next(new NavigationStart(1, 'start'));
expect(component.isLoading).toBeTruthy();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.