2016-12-11 99 views
6

当我运行这个单元测试:未处理的承诺拒绝:不能匹配任何路由

it('can click profile link in template',() => { 
    const landingPageLinkDe = linkDes[0]; 
    const profileLinkDe = linkDes[1]; 
    const aboutLinkDe = linkDes[2]; 
    const findLinkDe = linkDes[3]; 
    const addLinkDe = linkDes[4]; 
    const registerLinkDe = linkDes[5]; 
    const landingPageLinkFull = links[0]; 
    const profileLinkFull = links[1]; 
    const aboutLinkFull = links[2]; 
    const findLinkFull = links[3]; 
    const addLinkFull = links[4]; 
    const registerLinkFull = links[5]; 

    navFixture.detectChanges(); 
    expect(profileLinkFull.navigatedTo) 
     .toBeNull('link should not have navigated yet'); 
    profileLinkDe.triggerEventHandler('click', { button: 0 }); 
    landingPageLinkDe.triggerEventHandler('click', { button: 0 }); 
    aboutLinkDe.triggerEventHandler('click', { button: 0 }); 
    registerLinkDe.triggerEventHandler('click', { button: 0 }); 
    findLinkDe.triggerEventHandler('click', { button: 0 }); 
    addLinkDe.triggerEventHandler('click', { button: 0 }); 

    navFixture.detectChanges(); 
    expect(landingPageLinkFull.navigatedTo).toBe('/'); 
    expect(profileLinkFull.navigatedTo).toBe('/profile'); 
    expect(aboutLinkFull.navigatedTo).toBe('/about'); 
    expect(findLinkFull.navigatedTo).toBe('/find'); 
    expect(addLinkFull.navigatedTo).toBe('/add'); 
    expect(registerLinkFull.navigatedTo).toBe('/register'); 
}); 

我得到这个错误:

zone.js:388 Unhandled Promise rejection: Cannot match any routes. URL Segment: 'add' ; Zone: ProxyZone ; Task: Promise.then ; Value: Error: Cannot match any routes. URL Segment: 'add'(…) Error: Cannot match any routes. URL Segment: 'add'

测试仍然通过但它会是有趣的,知道我为什么会得到错误。当我使用应用程序时,我不会收到错误信息。我研究了这个错误,通常是由于在路由中没有提供默认路径,但是我已经完成了。

我做错了什么导致这个错误?

navbar.component.spec.ts

import 'zone.js/dist/long-stack-trace-zone.js'; 
import 'zone.js/dist/async-test.js'; 
import 'zone.js/dist/fake-async-test.js'; 
import 'zone.js/dist/sync-test.js'; 
import 'zone.js/dist/proxy.js'; 
import 'zone.js/dist/jasmine-patch.js'; 

import { 
    ComponentFixture, 
    TestBed, 
    async, 
    fakeAsync 
} from '@angular/core/testing'; 
import { 
    BrowserDynamicTestingModule, 
    platformBrowserDynamicTesting 
} from '@angular/platform-browser-dynamic/testing'; 
import { By } from '@angular/platform-browser'; 
import { 
    DebugElement, 
    Component, 
    ViewChild, 
    Pipe, 
    PipeTransform, 
    CUSTOM_ELEMENTS_SCHEMA, 
    NO_ERRORS_SCHEMA 
} from '@angular/core'; 
import { DatePipe } from '@angular/common'; 
import { Router, RouterOutlet, RouterModule } from '@angular/router'; 
import { RouterTestingModule } from '@angular/router/testing'; 
import { NavbarComponent } from './navbar.component'; 
import { RouterLinkStubDirective } from '../../router-stubs'; 
import { click } from '../../test/utilities.spec'; 

describe('NavbarComponent',() => { 
    let navComponent: NavbarComponent; 
    let navFixture: ComponentFixture<NavbarComponent>; 
    let linkDes: any; 
    let links: any; 
    let landingPageLink: any; 
    let profileLink: any; 
    let aboutLink: any; 
    let findLink: any; 
    let addLink: any; 
    let registerLink: any; 

    beforeAll(() => { 
     TestBed.resetTestEnvironment(); 
     TestBed.initTestEnvironment(BrowserDynamicTestingModule, 
      platformBrowserDynamicTesting()); 
    }); 

    beforeEach(async(() => { 
     TestBed.configureTestingModule({ 
      declarations: [ 
       NavbarComponent, 
       RouterLinkStubDirective 
      ], 
      imports: [RouterTestingModule], 
      schemas: [NO_ERRORS_SCHEMA] 
     }).compileComponents(); 
    })); 

    beforeEach(() => { 
     navFixture = TestBed.createComponent(NavbarComponent); 
     navComponent = navFixture.componentInstance; 
     navFixture.detectChanges(); 
     linkDes = navFixture.debugElement 
      .queryAll(By.directive(RouterLinkStubDirective)); 
     links = linkDes 
      .map((de: any) => de.injector 
       .get(RouterLinkStubDirective) as RouterLinkStubDirective); 
     landingPageLink = links[0].linkParams; 
     profileLink = links[1].linkParams; 
     aboutLink = links[2].linkParams; 
     findLink = links[3].linkParams; 
     addLink = links[4].linkParams; 
     registerLink = links[5].linkParams; 
    }); 

    it('can get RouterLinks from template',() => { 
     expect(links.length).toBe(6, 'should have 6 links'); 
     expect(landingPageLink[0]) 
      .toEqual('/', '1st link should go to landing page'); 
     expect(profileLink[0]) 
      .toEqual('/profile', '2nd link should go to profile'); 
     expect(aboutLink[0]) 
      .toEqual('/about', '3rd link should go to about'); 
     expect(findLink[0]) 
      .toEqual('/find', '4th link should go to find'); 
     expect(addLink[0]) 
      .toEqual('/add', '5th link should go to add'); 
     expect(registerLink[0]) 
      .toEqual('/register', '6th link should go to register'); 
    }); 

    it('can click profile link in template',() => { 
     const landingPageLinkDe = linkDes[0]; 
     const profileLinkDe = linkDes[1]; 
     const aboutLinkDe = linkDes[2]; 
     const findLinkDe = linkDes[3]; 
     const addLinkDe = linkDes[4]; 
     const registerLinkDe = linkDes[5]; 
     const landingPageLinkFull = links[0]; 
     const profileLinkFull = links[1]; 
     const aboutLinkFull = links[2]; 
     const findLinkFull = links[3]; 
     const addLinkFull = links[4]; 
     const registerLinkFull = links[5]; 

     navFixture.detectChanges(); 
     expect(profileLinkFull.navigatedTo) 
      .toBeNull('link should not have navigated yet'); 
     profileLinkDe.triggerEventHandler('click', { button: 0 }); 
     landingPageLinkDe.triggerEventHandler('click', { button: 0 }); 
     aboutLinkDe.triggerEventHandler('click', { button: 0 }); 
     registerLinkDe.triggerEventHandler('click', { button: 0 }); 
     findLinkDe.triggerEventHandler('click', { button: 0 }); 
     addLinkDe.triggerEventHandler('click', { button: 0 }); 

     navFixture.detectChanges(); 
     expect(landingPageLinkFull.navigatedTo).toBe('/'); 
     expect(profileLinkFull.navigatedTo).toBe('/profile'); 
     expect(aboutLinkFull.navigatedTo).toBe('/about'); 
     expect(findLinkFull.navigatedTo).toBe('/find'); 
     expect(addLinkFull.navigatedTo).toBe('/add'); 
     expect(registerLinkFull.navigatedTo).toBe('/register'); 
    }); 
}); 

存根用于测试:

import 'zone.js/dist/long-stack-trace-zone.js'; 
import 'zone.js/dist/async-test.js'; 
import 'zone.js/dist/fake-async-test.js'; 
import 'zone.js/dist/sync-test.js'; 
import 'zone.js/dist/proxy.js'; 
import 'zone.js/dist/jasmine-patch.js'; 

import { 
    EventEmitter, 
    Output, 
    trigger, 
    state, 
    style, 
    transition, 
    animate, 
    Directive, 
    Input 
} from '@angular/core'; 

import { 
    ComponentFixture, 
    TestBed, 
    async, 
    fakeAsync 
} from '@angular/core/testing'; 
import { 
    BrowserDynamicTestingModule, 
    platformBrowserDynamicTesting 
} from '@angular/platform-browser-dynamic/testing'; 
import { By } from '@angular/platform-browser'; 
import { 
    DebugElement, 
    Component, 
    ViewChild, 
    Pipe, 
    PipeTransform 
} from '@angular/core'; 
import { DatePipe } from '@angular/common'; 
import { Router } from '@angular/router'; 
import { NavbarComponent } from './shared/subcomponents/navbar.component'; 
import { AppComponent } from './app.component'; 
import { click } from './test/utilities.spec'; 

import { FormsModule, ReactiveFormsModule } from '@angular/forms' 

@Directive({ 
    selector: '[routerLink]', 
    host: { 
    '(click)': 'onClick()' 
    } 
}) 
export class RouterLinkStubDirective { 
    @Input('routerLink') linkParams: any; 
    navigatedTo: any = null; 

    onClick() { 
    this.navigatedTo = this.linkParams[0]; 
    } 
} 

app.routes.ts:

import { Routes } from '@angular/router'; 
import { LandingPageComponent } from './landing-page/landing-page.component'; 
import { FindPageComponent } from './find-page/find-page.component'; 
import { AddPageComponent } from './add-page/add-page.component'; 
import { RegisterPageComponent } from './register-page/register-page.component'; 
import { AboutPageComponent } from './about-page/about-page.component'; 
import { ProfilePageComponent } from './profile-page/profile-page.component'; 

export const routerConfig: Routes = [ 
    { 
    path: '', 
    component: LandingPageComponent 
    }, 
    { 
    path: '', 
    redirectTo: '', 
    pathMatch: 'full' 
    }, 
    { 
    path: 'find', 
    component: FindPageComponent 
    }, 
    { 
    path: 'add', 
    component: AddPageComponent 
    }, 
    { 
    path: 'register', 
    component: RegisterPageComponent 
    }, 
    { 
    path: 'about', 
    component: AboutPageComponent 
    }, 
    { 
    path: 'profile', 
    component: ProfilePageComponent 
    } 
]; 

navbar.component.html:

<nav class="navbar navbar-dark navbar-fixed-top text-uppercase"> 
    <div class="container-fluid"> 
     <button  class="navbar-toggler hidden-md-up pull-xs-right" 
        type="button" 
        data-toggle="collapse" 
        data-target="#nav-content"> 
        &#9776; 
     </button> 
     <a class="navbar-brand" [routerLink]="['/']" 
     routerLinkActive="active">vepo</a> 
     <div class="collapse navbar-toggleable-sm" id="nav-content"> 
      <ul class="nav navbar-nav pull-xs-right"> 
       <li class="nav-item"> 
        <a class="nav-link" [routerLink]="['/profile']" 
        routerLinkActive="active">profile</a> 
       </li> 
       <li class="nav-item"> 
        <a class="nav-link" [routerLink]="['/about']" 
        routerLinkActive="active">about</a> 
       </li> 
       <li class="nav-item"> 
        <a class="nav-link" [routerLink]="['/find']" 
        routerLinkActive="active">find</a> 
       </li> 
       <li class="nav-item"> 
        <a class="nav-link" [routerLink]="['/add']" 
        routerLinkActive="active">add</a> 
       </li> 
       <li class="nav-item"> 
        <button type="button" class="as-text nav-link 
        text-uppercase" (click)="openModal()"> 
         login 
        </button> 
       </li> 
       <li class="nav-item"> 
        <a class="nav-link signup" [routerLink]="['/register']" 
        routerLinkActive="active">sign up free</a> 
       </li> 
      </ul> 
     </div> 
    </div> 
</nav> 
<login #modal></login> 
<router-outlet></router-outlet> 
+0

看看这个:http://stackoverflow.com/questions/37605119/ – ppovoski

回答

15

我最近有同样的问题。这是由于在组件的ngOnInit方法内调用router.navigate所致。测试试图创建组件,但在ngOnInit里面试图远离组件(因为没有满足某些条件)。

就我而言,我正在导入RouterTestingModule作为TestBed.configureTestingModule的一部分。所以要解决这个问题,我只需注册一个RouterTestingModule的路线。例如,假设您的导航电话看起来像router.navigate(['example']),并且它解析为。您可以设置测试如下:

RouterTestingModule.withRoutes([ 
    { path: 'example', component: ExampleComponent} 
]) 

做上述允许我的测试,而不发出Cannot match any routes运行错误。

对于它的价值,我认为更好的办法是存根路由器和公正的确认,就navigate适当调用制成。

+0

这个声明是否包含在'beforeEach'内? – forgottofly

+1

@forgottofly是的,你把它放在TestBed.configureTestingModule({imports:[...]})属性中 – spoida

相关问题