2016-11-22 8 views
13

Tworzę testów jednostkowych dla mojego NavBar Komponentu i dostaję błąd:kątowa 2 Jasmine nie może wiązać się z „routerLink”, ponieważ nie jest znana własność „a”

Can't bind to 'routerLink' since it isn't a known property of 'a'

pasek nawigacyjny Komponent TS

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 
import { NavActiveService } from '../../../services/navactive.service'; 
import { GlobalEventsManager } from '../../../services/GlobalEventsManager'; 

@Component({ 
    moduleId: module.id, 
    selector: 'my-navbar', 
    templateUrl: 'navbar.component.html', 
    styleUrls:['navbar.component.css'], 
    providers: [NavActiveService] 
}) 
export class NavComponent { 
    showNavBar: boolean = true; 

    constructor(private router: Router, 
       private navactiveservice:NavActiveService, 
       private globalEventsManager: GlobalEventsManager){ 

    this.globalEventsManager.showNavBar.subscribe((mode:boolean)=>{ 
     this.showNavBar = mode; 
    }); 

    } 

} 

pasek nawigacyjny Komponent Spec

import { ComponentFixture, TestBed, async } from '@angular/core/testing';  
import { NavComponent } from './navbar.component'; 
import { DebugElement } from '@angular/core'; 
import { By }    from '@angular/platform-browser'; 
import { Router } from '@angular/router'; 

export function main() { 
    describe('Navbar component',() => { 

     let de: DebugElement; 
     let comp: NavComponent; 
     let fixture: ComponentFixture<NavComponent>; 
     let router: Router; 

     // preparing module for testing 
     beforeEach(async(() => { 
      TestBed.configureTestingModule({ 
       declarations: [NavComponent], 
      }).compileComponents().then(() => { 

       fixture = TestBed.createComponent(NavComponent); 
       comp = fixture.componentInstance; 
       de = fixture.debugElement.query(By.css('p')); 

      }); 
     })); 


     it('should create component',() => expect(comp).toBeDefined()); 


/*  it('should have expected <p> text',() => { 
      fixture.detectChanges(); 
      const h1 = de.nativeElement; 
      expect(h1.innerText).toMatch(" "); 
     });*/ 


    }); 
} 

Zdaję sobie sprawę, że muszę dodać router jako szpiega, ale jeśli dodaję go jako SpyObj i zadeklaruję go jako dostawcę, otrzymam ten sam błąd.

Czy jest lepszy sposób, aby dodać ten błąd?

EDIT: Working Test jednostki

Wbudowany test jednostki w oparciu o odpowiedź:

import { ComponentFixture, TestBed, async } from '@angular/core/testing'; 
import { NavComponent } from './navbar.component'; 
import { DebugElement } from '@angular/core'; 
import { By }    from '@angular/platform-browser'; 
import { RouterLinkStubDirective, RouterOutletStubComponent } from '../../../../test/router-stubs'; 
import { Router } from '@angular/router'; 
import { GlobalEventsManager } from '../../../services/GlobalEventsManager'; 
import { RouterModule } from '@angular/router'; 
import { SharedModule } from '../shared.module'; 


export function main() { 
    let comp: NavComponent; 
    let fixture: ComponentFixture<NavComponent>; 
    let mockRouter:any; 
    class MockRouter { 
     //noinspection TypeScriptUnresolvedFunction 
     navigate = jasmine.createSpy('navigate'); 
    } 

    describe('Navbar Componenet',() => { 

     beforeEach(async(() => { 
      mockRouter = new MockRouter(); 
      TestBed.configureTestingModule({ 
       imports: [ SharedModule ] 
      }) 

      // Get rid of app's Router configuration otherwise many failures. 
      // Doing so removes Router declarations; add the Router stubs 
       .overrideModule(SharedModule, { 
        remove: { 
         imports: [ RouterModule ], 

        }, 
        add: { 
         declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ], 
         providers: [ { provide: Router, useValue: mockRouter }, GlobalEventsManager ], 
        } 
       }) 

       .compileComponents() 

       .then(() => { 
        fixture = TestBed.createComponent(NavComponent); 
        comp = fixture.componentInstance; 
       }); 
     })); 

     tests(); 
    }); 


     function tests() { 
      let links: RouterLinkStubDirective[]; 
      let linkDes: DebugElement[]; 

      beforeEach(() => { 
       // trigger initial data binding 
       fixture.detectChanges(); 

       // find DebugElements with an attached RouterLinkStubDirective 
       linkDes = fixture.debugElement 
        .queryAll(By.directive(RouterLinkStubDirective)); 

       // get the attached link directive instances using the DebugElement injectors 
       links = linkDes 
        .map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective); 
      }); 

      it('can instantiate it',() => { 
       expect(comp).not.toBeNull(); 
      }); 

      it('can get RouterLinks from template',() => { 
       expect(links.length).toBe(5, 'should have 5 links'); 
       expect(links[0].linkParams).toBe('/', '1st link should go to Home'); 
       expect(links[1].linkParams).toBe('/', '2nd link should go to Home'); 
expect(links[2].linkParams).toBe('/upload', '3rd link should go to Upload'); 
       expect(links[3].linkParams).toBe('/about', '4th link should to to About'); 
       expect(links[4].linkParams).toBe('/login', '5th link should go to Logout'); 
      }); 

      it('can click Home link in template',() => { 
       const uploadLinkDe = linkDes[1]; 
       const uploadLink = links[1]; 

       expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet'); 

       uploadLinkDe.triggerEventHandler('click', null); 
       fixture.detectChanges(); 

       expect(uploadLink.navigatedTo).toBe('/'); 
      }); 


      it('can click upload link in template',() => { 
       const uploadLinkDe = linkDes[2]; 
       const uploadLink = links[2]; 

       expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet'); 

       uploadLinkDe.triggerEventHandler('click', null); 
       fixture.detectChanges(); 

       expect(uploadLink.navigatedTo).toBe('/upload'); 
      }); 

      it('can click about link in template',() => { 
       const uploadLinkDe = linkDes[3]; 
       const uploadLink = links[3]; 

       expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet'); 

       uploadLinkDe.triggerEventHandler('click', null); 
       fixture.detectChanges(); 

       expect(uploadLink.navigatedTo).toBe('/about'); 
      }); 

      it('can click logout link in template',() => { 
       const uploadLinkDe = linkDes[4]; 
       const uploadLink = links[4]; 

       expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet'); 

       uploadLinkDe.triggerEventHandler('click', null); 
       fixture.detectChanges(); 

       expect(uploadLink.navigatedTo).toBe('/login'); 
      }); 
     } 
} 
+0

której wersji Angular używasz? ponieważ opcja dostawcy jest niedostępna w metadanych składników w ostatecznej wersji Angular 2 –

+0

Używam wersji 2.1.0. Czy masz na myśli, że dostarczanie nie jest już opcją do testów jednostkowych? Uważam, że nadal korzystasz z usług dostawców modułów. Używam ziarno kątowe i nadal są w tym przykładzie: https://github.com/mgechev/angular-seed/blob/master/src/client/app/home/home.module.ts – Bhetzie

+0

Byłem rozmowa o opcji 'dostawcy 'NavComponenta –

Odpowiedz

14

adresowej ng2 Testing docs tym za pomocą RouterLinkStubDirective i RouterOutletStubComponent tak że routerLink jest znaną właściwością < a>. Zasadniczo mówi, że używanie RouterOutletStubComponent jest bezpiecznym sposobem testowania routerLinks bez wszystkich komplikacji i błędów związanych z używaniem prawdziwego RouterOutlet. Twój projekt musi wiedzieć, że istnieje, więc nie powoduje błędów, ale nie musi w tym przypadku nic robić. RouterLinkStubDirective umożliwia kliknięcie na < a> linki z dyrektywą routerLink i uzyskanie wystarczającej ilości informacji do przetestowania, że ​​jest klikane (nawigacja) i udanie się na właściwą trasę (linkParams). Każda dodatkowa funkcjonalność i naprawdę nie testujesz już swojego komponentu w izolacji.

Spójrz na ich demo w app/app.component.spec.ts. Chwyć test/router-stubs.ts i dodaj do swojego projektu. Następnie wstrzykniesz 2 zgaszone elementy do deklaracji TestBed.

+0

Dziękuję, doceniam odniesienie do dokumentów w twojej odpowiedzi. – Bhetzie

+0

Dodano test mojej jednostki pracy, mam nadzieję, że pomogę komuś innemu, jeśli będą walczyć. Dzięki jeszcze raz! – Bhetzie

+0

Nie rozumiem, dlaczego te kody nie są wysyłane w/master – FlavorScape

Powiązane problemy