Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: this.router.createUrlTree is not a function

I am attempting to create a unit test for my navbar component. This component is the parent container for the app. For some reasons karma keeps giving me this error, I can't find any reference to it on the internet or how to fix it. Any help would be great, thanks

navBar.comp.spec.ts

    import { APP_BASE_HREF } from '@angular/common';
    import { By } from '@angular/platform-browser';
    import { ComponentFixture, ComponentFixtureAutoDetect, TestBed , async} from '@angular/core/testing';
    import { Router, ActivatedRoute, RouterModule, Routes } from '@angular/router';
    import { MdTabsModule } from '@angular/material';
    import { Observable } from 'rxjs';
    import { NavBarComponent } from './navBar.component';

    describe('NavBarComponent', () => {
        let comp: NavBarComponent;
        let fixture: ComponentFixture<NavBarComponent>;

        beforeEach(() => {
            const routes: Routes = [
                {
                  path: '',
                  component: NavBarComponent,
                }
            ];
            const routerStub = {
                events: Observable.of('/')
            };
            const activatedRouteStub = {
              params: Observable.of({'id': 1})
            };
            TestBed.configureTestingModule({
                declarations: [ NavBarComponent ],
                providers: [
                    { provide: Router, useValue: routerStub },
                    { provide: ActivatedRoute, useValue: activatedRouteStub },
                    { provide: APP_BASE_HREF, useValue: '/' },
                    { provide: ComponentFixtureAutoDetect, useValue: true }
                ],
                imports: [ MdTabsModule, MdTabsModule, RouterModule.forRoot(routes) ],
            });
            spyOn(NavBarComponent.prototype, 'setActiveIndex');
            spyOn(NavBarComponent.prototype, 'getActiveIndex');
            fixture = TestBed.createComponent(NavBarComponent);
            comp = fixture.componentInstance;
        });

        it('should set navbmobile', async(() => {
          fixture.detectChanges();

          fixture.whenStable().then(() => {
            fixture.detectChanges();
            expect(fixture.debugElement.query(By.css('#navBMobile')).nativeElement.style.display).toBe("");
          })
        }))

    });

navBar.comp.html

    <nav [style.display]="style" id="navB" md-tab-nav-bar aria-label="Navigation links">
      <a md-tab-link
        *ngFor="let routeLink of routeLinks; let i = index"
        [routerLink]="routeLink.link"
        [active]="activeLinkIndex === i"
        (click)="activeLinkIndex = i">
        {{routeLink.label}}
      </a>
    </nav>

    <nav [style.display]="style" id="navBMobile" md-tab-nav-bar aria-label="Navigation links">
      <md-card id="mobileNav">
      <a md-tab-link
        *ngFor="let routeLink of mobileRouteLinks; let i = index"
        [routerLink]="routeLink.link"
        [active]="activeLinkIndex === i"
        (click)="activeLinkIndex = i"
        style="width:10%">
        <div class="mobileButtons" [innerHtml]="routeLink.label"></div>
      </a>
      </md-card>
    </nav>

    <router-outlet></router-outlet>

navBar.comp.ts

    import { Component } from '@angular/core';
    import { Router } from '@angular/router';

    @Component({
      selector: 'app-nav-bar',
      templateUrl: 'navBar.component.html'
    })
    export class NavBarComponent {
      public activeIndex = 2 ;
      activeLinkIndex: number;
      mobileRouteLinks: any[];
      routeLinks: any[];
      style: string;

      constructor(
        private router: Router
      ) {
        this.style = 'none';

        router.events.subscribe((url: any) => {
          this.setActiveIndex(url.url);
          this.activeLinkIndex = this.getActiveIndex();
        });

        this.routeLinks = [
          {label: 'Profile', link: '/profile/', index: '0'},
          {label: 'Notifications', link: '/notifications/', index: '1'},
          {label: 'Home', link: '', index: '2'},
          {label: 'My Posts', link: '/posts/', index: '3'},
          {label: 'Create a Post', link: '/create/', index: '4'}
        ];

        this.mobileRouteLinks = [
          {label: '<i class="material-icons">perm_identity</i>', link: '/profile/', index: '0'},
          {label: '<i class="material-icons">notifications_none</i>', link: '/notifications/', index: '1'},
          {label: '<i class="material-icons">home</i>', link: '', index: '2'},
          {label: '<i class="material-icons">content_copy</i>', link: '/posts/', index: '3'},
          {label: '<i class="material-icons">create</i>', link: '/create/', index: '4'}
        ];
      }

      setActiveIndex(s: string) {
        if (s === '/profile') {
          this.activeIndex = 0;
        } else if (s === '/notifications') {
          this.activeIndex = 1;
        } else if (s === '/') {
          this.activeIndex = 2;
        } else if (s === '/posts') {
          this.activeIndex = 3;
        } else if (s === '/create') {
          this.activeIndex = 4;
        }
      }

      getActiveIndex(): number {
        return this.activeIndex;
      }
    }
like image 381
Cameron Gilbert Avatar asked Oct 30 '17 23:10

Cameron Gilbert


1 Answers

As you provided a stub for the Router in your unit test, you need to define the fonction in your stub as well (code should work):

const routerStub = {
    events: Observable.of('/'),
    createUrlTree: (commands, navExtras = {}) => {}
};
like image 62
merlosy Avatar answered Oct 01 '22 01:10

merlosy