模拟 Angular 路由器与旁观者
Mock Angular Router with Spectator
我正在使用 Spectator to write my Angular 8 tests and Jest 到 运行 他们。我是前端单元测试的新手,所以我可能忽略了一些简单的事情;欢迎任何想法。
我有以下方法(在 Typescript 中)return 是一个布尔值,基于当前 URL 是否匹配一组路径(不包括 queryParams 和片段):
// custom-breadcrumb.component.ts
private blacklistedPaths: string[] = [''];
constructor(private router: Router) {
}
hideBreadcrumb(): boolean {
let primaryUrlSegmentGroup: UrlSegmentGroup = this.router.parseUrl(this.router.url).root.children['primary'];
if(primaryUrlSegmentGroup == null){
return true;
}
let urlPath = primaryUrlSegmentGroup.segments.map((segment: UrlSegment) => segment.path).join('/');
return this.blacklistedPaths.some((path: string) => path === urlPath);
}
和
// custom-breadcrumb.component.html
<xng-breadcrumb [hidden]="hideBreadcrumb()">
<ng-container *xngBreadcrumbItem="let breadcrumb">
...
</ng-container>
</xng-breadcrumb>
我现在想用 Spectator 编写测试,以根据几个可能的 url 验证布尔 return 值。在 Java 中,我将使用模拟对象模拟 Router
并执行以下操作:
when(mockObject.performMethod()).thenReturn(myReturnValue);
如何为 Router
创建模拟?我如何定义 this.router.parseUrl(this.router.url).root.children['primary']
的 return 值?
这是我目前拥有的:
// custom-breadcrumb.component.spec.ts
import {SpectatorRouting, createRoutingFactory} from '@ngneat/spectator/jest';
describe('CustomBreadcrumbComponent', () => {
let spectator: SpectatorRouting<CustomBreadcrumbComponent>;
const createComponent = createRoutingFactory({
component: CustomBreadcrumbComponent,
declarations: [
MockComponent(BreadcrumbComponent),
MockPipe(CapitalizePipe)
],
routes: [{path: ''}] // I don't think this works
});
beforeEach(() => spectator = createComponent());
it('hideBreadcrumb - hide on homepage', () => {
// TODO set url path to ''
expect(spectator.component.hideBreadcrumb()).toBeTruthy();
});
it('hideBreadcrumb - show on a page other than homepage', () => {
//TODO set url path to 'test' for example
expect(spectator.component.hideBreadcrumb()).toBeFalsy();
});
});
我知道 createRoutingFactory
提供开箱即用的 ActivatedRouteStub
,但我无法用它做任何有意义的事情。
PS:我添加了业力作为标签,因为它可能有相同的解决方案,但如果我错了请纠正我。
我的印象是 spectator.router
是 return 对我的嘲笑,而我必须使用 spectator.get<Router>(Router)
才能得到它。我遇到的另一个问题是 html 模板中的 hideBreadcrumb
方法在组件创建时被加载,而我还没有机会模拟 Router
。我是这样解决的:
将 detectChanges
设置为 false 以防止在我创建旁观者组件时加载 html 模板和 ngOnInit:
let spectator: SpectatorRouting<CustomBreadcrumbComponent>;
const createComponent = createRoutingFactory({
detectChanges: false,
component: CustomBreadcrumbComponent,
declarations: [ ... ]
});
beforeEach(() => {
spectator = createComponent()
});
现在它不会调用 hideBreadcrumb()
,这允许成功创建观察者。
我的测试是这样的:
it('hideBreadcrumb - hide on homepage', () => {
let routerMock = spectator.get<Router>(Router);
routerMock.parseUrl.andReturn({root: {children: {'primary': {segments: [{path: ''}]}}}});
spectator.detectChanges();
expect(spectator.component.hideBreadcrumb()).toBeTruthy();
});
我使用 spectator.get<Router>(Router)
从旁观者那里检索了一个模拟,并模拟了 parseUrl
方法的 return 值。我现在通过设置 spectator.detectChanges()
.
允许 html 模板和 ngOnInit
进度
我正在使用 Spectator to write my Angular 8 tests and Jest 到 运行 他们。我是前端单元测试的新手,所以我可能忽略了一些简单的事情;欢迎任何想法。
我有以下方法(在 Typescript 中)return 是一个布尔值,基于当前 URL 是否匹配一组路径(不包括 queryParams 和片段):
// custom-breadcrumb.component.ts
private blacklistedPaths: string[] = [''];
constructor(private router: Router) {
}
hideBreadcrumb(): boolean {
let primaryUrlSegmentGroup: UrlSegmentGroup = this.router.parseUrl(this.router.url).root.children['primary'];
if(primaryUrlSegmentGroup == null){
return true;
}
let urlPath = primaryUrlSegmentGroup.segments.map((segment: UrlSegment) => segment.path).join('/');
return this.blacklistedPaths.some((path: string) => path === urlPath);
}
和
// custom-breadcrumb.component.html
<xng-breadcrumb [hidden]="hideBreadcrumb()">
<ng-container *xngBreadcrumbItem="let breadcrumb">
...
</ng-container>
</xng-breadcrumb>
我现在想用 Spectator 编写测试,以根据几个可能的 url 验证布尔 return 值。在 Java 中,我将使用模拟对象模拟 Router
并执行以下操作:
when(mockObject.performMethod()).thenReturn(myReturnValue);
如何为 Router
创建模拟?我如何定义 this.router.parseUrl(this.router.url).root.children['primary']
的 return 值?
这是我目前拥有的:
// custom-breadcrumb.component.spec.ts
import {SpectatorRouting, createRoutingFactory} from '@ngneat/spectator/jest';
describe('CustomBreadcrumbComponent', () => {
let spectator: SpectatorRouting<CustomBreadcrumbComponent>;
const createComponent = createRoutingFactory({
component: CustomBreadcrumbComponent,
declarations: [
MockComponent(BreadcrumbComponent),
MockPipe(CapitalizePipe)
],
routes: [{path: ''}] // I don't think this works
});
beforeEach(() => spectator = createComponent());
it('hideBreadcrumb - hide on homepage', () => {
// TODO set url path to ''
expect(spectator.component.hideBreadcrumb()).toBeTruthy();
});
it('hideBreadcrumb - show on a page other than homepage', () => {
//TODO set url path to 'test' for example
expect(spectator.component.hideBreadcrumb()).toBeFalsy();
});
});
我知道 createRoutingFactory
提供开箱即用的 ActivatedRouteStub
,但我无法用它做任何有意义的事情。
PS:我添加了业力作为标签,因为它可能有相同的解决方案,但如果我错了请纠正我。
我的印象是 spectator.router
是 return 对我的嘲笑,而我必须使用 spectator.get<Router>(Router)
才能得到它。我遇到的另一个问题是 html 模板中的 hideBreadcrumb
方法在组件创建时被加载,而我还没有机会模拟 Router
。我是这样解决的:
将 detectChanges
设置为 false 以防止在我创建旁观者组件时加载 html 模板和 ngOnInit:
let spectator: SpectatorRouting<CustomBreadcrumbComponent>;
const createComponent = createRoutingFactory({
detectChanges: false,
component: CustomBreadcrumbComponent,
declarations: [ ... ]
});
beforeEach(() => {
spectator = createComponent()
});
现在它不会调用 hideBreadcrumb()
,这允许成功创建观察者。
我的测试是这样的:
it('hideBreadcrumb - hide on homepage', () => {
let routerMock = spectator.get<Router>(Router);
routerMock.parseUrl.andReturn({root: {children: {'primary': {segments: [{path: ''}]}}}});
spectator.detectChanges();
expect(spectator.component.hideBreadcrumb()).toBeTruthy();
});
我使用 spectator.get<Router>(Router)
从旁观者那里检索了一个模拟,并模拟了 parseUrl
方法的 return 值。我现在通过设置 spectator.detectChanges()
.
ngOnInit
进度