代码之家  ›  专栏  ›  技术社区  ›  Aleksandr Havrylov

角度路由器、面包屑组件测试

  •  0
  • Aleksandr Havrylov  · 技术社区  · 8 年前

    我有 测试见下文。测试覆盖率应超过75%。测试失败,因为 ActivatedRoute.root.children 未定义。谁知道我怎么定义它?我至少需要一个

    面包屑.组件:

    import { Component, OnInit } from '@angular/core';
    import {
     Router,
     ActivatedRoute,
     NavigationEnd,
     Params,
     PRIMARY_OUTLET
    } from '@angular/router';
    
    import { Breadcrumb } from './breadcrumbs.interface.component';
    import * as _ from 'lodash';
    import 'rxjs/add/operator/filter';
    
    @Component({
     selector: 'breadcrumbs',
     styleUrls: ['./breadcrumbs.component.scss'],
     templateUrl: './breadcrumbs.component.html'
    })
    
    export class BreadcrumbsComponent implements OnInit {
    private breadcrumbs: Breadcrumb[];
    
    constructor(
        private router: Router,
        private activatedRoute: ActivatedRoute,
        ) {
    }
    public ngOnInit() {
        this.breadcrumbs = [];
        this.router.events.filter((event) => event instanceof NavigationEnd)
        .subscribe((event: NavigationEnd) => {
            let id = event.url;
            let root: ActivatedRoute = this.activatedRoute.root;
            this.breadcrumbs = this.getBreadcrumbs(root, '/main', this.breadcrumbs, id);
        });
    }
    
    public goTo = (breadcrumb) => this.router.navigateByUrl(breadcrumb.path);
    
    private getBreadcrumbs(
        route: ActivatedRoute,
        url: string = '',
        breadcrumbs: Breadcrumb[] = [],
        id: string
        ): Breadcrumb[] {
        const ROUTE_DATA_BREADCRUMB: string = 'title';
        // get the child routes
        let children: ActivatedRoute[] = route.children;
    
        // return if there are no more children
        if (children.length === 0) {
            return breadcrumbs;
        }
    
        // iterate over each children
        for (let child of children) {
            // verify primary route
            if (child.outlet !== PRIMARY_OUTLET) {
                continue;
            }
    
            // verify the custom data property "breadcrumb" is specified on the route
            if (!child.snapshot.data.hasOwnProperty(ROUTE_DATA_BREADCRUMB)) {
                return this.getBreadcrumbs(child, url, breadcrumbs, id);
            }
            // get the route's URL segment
            let routeURL: string = child.snapshot.url.map((segment) => segment.path).join('/');
    
            // append route URL to URL
            url += `/${routeURL}`;
            let title = child.snapshot.data[ROUTE_DATA_BREADCRUMB]
            || child.snapshot.params[ROUTE_DATA_BREADCRUMB];
            let isNew = child.snapshot.data['new'];
            // add breadcrumb
            let breadcrumb: Breadcrumb = {
                title,
                params: child.snapshot.params,
                url,
                id
            };
            if (isNew) {
                breadcrumbs = [breadcrumb];
            } else {
                let index = _.findLastIndex(breadcrumbs, { id });
                if (index > -1) {
                    breadcrumbs.splice(index + 1);
                } else {
                    breadcrumbs.push(breadcrumb);
                }
            }
    
            // recursive
            return this.getBreadcrumbs(child, url, breadcrumbs, id);
        }
    
        // we should never get here, but just in case
        return breadcrumbs;
    }
    }
    

    面包屑.component.spec:

    import {
     TestBed,
     ComponentFixture,
     async,
     inject
    } from '@angular/core/testing';
    import { Component } from '@angular/core';
    import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
    import { RouterTestingModule } from '@angular/router/testing';
    import { NoopAnimationsModule } from '@angular/platform-browser/animations';
    import { CommonModule } from '@angular/common';
    
    import { BreadcrumbsComponent } from './breadcrumbs.component';
    import { RouterLinkStubDirective, ActivatedRouteMock, MockComponent } from '../../testing';
    import { Observable } from 'rxjs/Observable';
    import { of } from 'rxjs/observable/of';
    
    class RouterStub {
    public navigate = jasmine.createSpy('navigate');
    public ne = new NavigationEnd(0,
        '/main/sps',
        '/main/sps');
    public events = new Observable((observer) => {
        observer.next(this.ne);
        observer.complete();
    });
    public navigateByUrl(url: string) { location.hash = url; }
    }
    
    let ROUTES = [
    {
        path: 'main',
        component: MockComponent,
        children: [
            {
                path: 'link1',
                component: MockComponent
            },
            {
                path: 'link2',
                component: MockComponent
            },
        ]
    },
    {
        path: '',
        component: MockComponent,
    },
    ];
    
    describe('Component: BreadcrumbsComponent', () => {
    let comp: BreadcrumbsComponent;
    let fixture: ComponentFixture<BreadcrumbsComponent>;
    let routerStub = new RouterStub();
    let mockActivatedRoute = new ActivatedRouteMock();
    let router: Router;
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                BreadcrumbsComponent,
                RouterLinkStubDirective,
                MockComponent
            ],
            providers: [
                { provide: Router, useValue: routerStub },
                { provide: ActivatedRoute, useValue: mockActivatedRoute },
            ],
            imports: [
                NoopAnimationsModule,
                CommonModule,
                RouterTestingModule.withRoutes(ROUTES)
            ]
        })
            .compileComponents()
            .then(() => {
                fixture = TestBed.createComponent(BreadcrumbsComponent);
                comp = fixture.componentInstance;
                fixture.detectChanges();
            });
    }));
    it('should be init', () => {
        expect(comp).toBeTruthy();
    });
    });
    

    应该是init Chrome 58.0.3029(Mac OS X 10.12.3)组件:BreadcrumbsComponent应为init失败 TypeError:无法读取未定义的属性“children” 在面包屑组件。获取面包屑(webpack:///src/app/components/breadcrumbs/breadcrumbs.component.ts:33:29<-配置/规范包.js:122693:43) 在SafeSubscriber_下一个(webpack:///src/app/components/breadcrumbs/breadcrumbs.component.ts:25:38<-配置/规范包。js:122692:1206)

    enter image description here

    1 回复  |  直到 8 年前
        1
  •  1
  •   Markus    8 年前

    不确定您是如何模拟ActivatedRoute的,但我们是这样使用它的:

    { provide: ActivatedRoute, useValue: { params: Observable.of({ productcode: product.id }) }},
    

    因此,您可能还可以在那里设置根和子对象,类似于

    { provide: ActivatedRoute, useValue: { root: { children: ['something'] } }},