【问题标题】:Mock Angular Router with Spectator带旁观者的模拟 Angular 路由器
【发布时间】:2020-03-31 21:03:51
【问题描述】:

我使用Spectator 编写我的Angular 8 测试并使用Jest 运行它们。我是前端单元测试的新手,所以我可能忽略了一些简单的事情;欢迎任何想法。

我有以下方法(在 Typescript 中),它根据当前 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 验证布尔返回值。在 Java 中,我会用模拟对象模拟 Router 并执行以下操作:

when(mockObject.performMethod()).thenReturn(myReturnValue);

如何为Router 创建模拟?以及如何定义this.router.parseUrl(this.router.url).root.children['primary'] 的返回值?

这是我目前拥有的:

// 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:我添加了 karma 作为标签,因为它可能有相同的解决方案,但如果我错了,请纠正我。

【问题讨论】:

    标签: angular jestjs karma-jasmine ngmock angular-spectator


    【解决方案1】:

    我的印象是spectator.router 正在给我返回一个模拟,而我必须使用spectator.get&lt;Router&gt;(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&lt;Router&gt;(Router) 从观众那里检索一个模拟,并模拟parseUrl 方法的返回值。我现在通过设置 spectator.detectChanges() 来允许 html 模板和 ngOnInit 进程。

    【讨论】:

      猜你喜欢
      • 2021-12-14
      • 2012-05-02
      • 2017-02-12
      • 2017-02-26
      • 2010-09-18
      • 2017-03-04
      • 2022-11-04
      • 1970-01-01
      • 2015-05-11
      相关资源
      最近更新 更多