为 angular 中 router.events.subscribe 的 "ActivationEnd" 事件编写单元测试
Write unit test for "ActivationEnd" event from router.events.subscribe in angular
我需要帮助才能为 router.events.subscribe
编写单元测试。我使用 ActivationEnd
来使用快照对象,它具有我的应用程序所需的属性。路由器中没有其他事件提供这些,所以我必须坚持这个 ActivationEnd
。但是我没有得到关于如何模拟这个 snapshot 对象的任何信息。
下面是我的代码片段。
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof ActivationEnd) {
this.section = e.snapshot.data.title;
this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
}
});
}
你能帮我做些什么来实现这个或任何替代方案的单元测试吗?
此致,
阿尔佩什
我有时会混合使用 jasmine.createSpyObj 和 json 对象,也许这会对您有所帮助:
const activationEndMock = {
...jasmine.createSpyObj(['']),
snapshot: {
data: {
title: 'a title'
},
routeConfig: {
data: {
label: 'a label'
}
}
}
}
const routerMock = {
...jasmine.createSpyObj<Router>(['']),
events: of(activationEndMock)
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [{ provide: Router, useValue: routerMock }]
});
.........
});
我不确定这是否有效,因为我没有测试它。
比方说,你有这样一个组件:
import { Component, OnInit } from '@angular/core';
import { ActivationEnd, Router } from '@angular/router';
@Component({
selector: 'app-test-router',
templateUrl: './test-router.component.html',
styleUrls: ['./test-router.component.css']
})
export class TestRouterComponent implements OnInit {
section = '';
dynamicSubNavLabel = '';
constructor(private router: Router) { }
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof ActivationEnd) {
this.section = e.snapshot.data.title;
this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
}
});
}
}
因为 Router.events
已经是 Subject<Event>
。我们可以这样做:
- 我们将其转换为
Subject<Event>
,然后调用 next
发出我们的 custom/mock ActivationEnd 事件。
- 首先将我们的模拟数据转换为未知,然后转换为 ActivatedRouteSnapshot。
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, ActivationEnd, Event, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Subject } from 'rxjs';
import { TestRouterComponent } from './test-router.component';
describe('TestRouterComponent', () => {
let component: TestRouterComponent;
let fixture: ComponentFixture<TestRouterComponent>;
let router: Router;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ TestRouterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestRouterComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should update data from router', () => {
const events$ = router.events as Subject<Event>;
const mockSnapshot = {
data: {
title: 'some heading'
},
routeConfig: {
data: {
label: 'some text'
}
}
} as unknown as ActivatedRouteSnapshot;
events$.next(new ActivationEnd(mockSnapshot));
expect(component.section).toBeTruthy();
expect(component.dynamicSubNavLabel).toBeTruthy();
})
});
来自 Angular 的源代码:https://github.com/angular/angular/blob/75a3c778b1f7be913f0287423d40fade68ee9adc/packages/router/src/router.ts#L461
我需要帮助才能为 router.events.subscribe
编写单元测试。我使用 ActivationEnd
来使用快照对象,它具有我的应用程序所需的属性。路由器中没有其他事件提供这些,所以我必须坚持这个 ActivationEnd
。但是我没有得到关于如何模拟这个 snapshot 对象的任何信息。
下面是我的代码片段。
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof ActivationEnd) {
this.section = e.snapshot.data.title;
this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
}
});
}
你能帮我做些什么来实现这个或任何替代方案的单元测试吗?
此致, 阿尔佩什
我有时会混合使用 jasmine.createSpyObj 和 json 对象,也许这会对您有所帮助:
const activationEndMock = {
...jasmine.createSpyObj(['']),
snapshot: {
data: {
title: 'a title'
},
routeConfig: {
data: {
label: 'a label'
}
}
}
}
const routerMock = {
...jasmine.createSpyObj<Router>(['']),
events: of(activationEndMock)
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [{ provide: Router, useValue: routerMock }]
});
.........
});
我不确定这是否有效,因为我没有测试它。
比方说,你有这样一个组件:
import { Component, OnInit } from '@angular/core';
import { ActivationEnd, Router } from '@angular/router';
@Component({
selector: 'app-test-router',
templateUrl: './test-router.component.html',
styleUrls: ['./test-router.component.css']
})
export class TestRouterComponent implements OnInit {
section = '';
dynamicSubNavLabel = '';
constructor(private router: Router) { }
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof ActivationEnd) {
this.section = e.snapshot.data.title;
this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
}
});
}
}
因为 Router.events
已经是 Subject<Event>
。我们可以这样做:
- 我们将其转换为
Subject<Event>
,然后调用next
发出我们的 custom/mock ActivationEnd 事件。 - 首先将我们的模拟数据转换为未知,然后转换为 ActivatedRouteSnapshot。
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, ActivationEnd, Event, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Subject } from 'rxjs';
import { TestRouterComponent } from './test-router.component';
describe('TestRouterComponent', () => {
let component: TestRouterComponent;
let fixture: ComponentFixture<TestRouterComponent>;
let router: Router;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ TestRouterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestRouterComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should update data from router', () => {
const events$ = router.events as Subject<Event>;
const mockSnapshot = {
data: {
title: 'some heading'
},
routeConfig: {
data: {
label: 'some text'
}
}
} as unknown as ActivatedRouteSnapshot;
events$.next(new ActivationEnd(mockSnapshot));
expect(component.section).toBeTruthy();
expect(component.dynamicSubNavLabel).toBeTruthy();
})
});
来自 Angular 的源代码:https://github.com/angular/angular/blob/75a3c778b1f7be913f0287423d40fade68ee9adc/packages/router/src/router.ts#L461