2016-11-22 15 views
13

tôi là tạo ra một thử nghiệm đơn vị cho Hợp phần Navbar của tôi và tôi nhận được một lỗi:góc 2 Jasmine Không thể liên kết với 'routerLink' vì nó không phải là một tài sản của tiếng 'a'

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

Navbar Component 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; 
    }); 

    } 

} 

Navbar Component 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(" "); 
     });*/ 


    }); 
} 

Tôi nhận ra rằng tôi cần phải thêm bộ định tuyến làm gián điệp, nhưng nếu tôi thêm nó dưới dạng SpyObj và khai báo nó là nhà cung cấp, tôi sẽ gặp lỗi tương tự.

Có cách nào tốt hơn để tôi thêm sửa lỗi này không?

EDIT: Working Unit Test

xây dựng kiểm tra đơn vị này dựa trên câu trả lời:

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

phiên bản Angular nào bạn đang sử dụng? vì tùy chọn 'provider' không có trên siêu dữ liệu thành phần trong phiên bản phát hành cuối cùng của Angular 2 –

+0

Tôi đang sử dụng phiên bản 2.1.0. Bạn có nghĩa là cung cấp không còn là một lựa chọn cho các bài kiểm tra đơn vị? Tôi tin rằng bạn vẫn sử dụng các nhà cung cấp trong các mô-đun. Tôi đang sử dụng hạt giống góc cạnh và chúng vẫn còn trong ví dụ: https://github.com/mgechev/angular-seed/blob/master/src/client/app/home/home.module.ts – Bhetzie

+0

Tôi đã nói về lựa chọn 'nhà cung cấp' của NavComponent' của bạn –

Trả lời

14

Địa chỉ ng2 Testing docs này bằng cách sử dụng RouterLinkStubDirective và RouterOutletStubComponent để routerLink một tài sản của tiếng < a>. Về cơ bản nó nói rằng việc sử dụng RouterOutletStubComponent là một cách an toàn để kiểm tra routerLinks mà không có tất cả các biến chứng và lỗi khi sử dụng RouterOutlet thực. Dự án của bạn cần phải biết nó tồn tại để nó không ném lỗi nhưng nó không cần phải thực sự làm bất cứ điều gì trong trường hợp này. RouterLinkStubDirective cho phép bạn nhấp vào < a> liên kết với chỉ thị routerLink và nhận đủ thông tin để kiểm tra xem nó đang được nhấp (navigatedTo) và đi đúng tuyến đường (linkParams) hay chưa. Bất kỳ chức năng nào nhiều hơn thế và bạn thực sự không thử nghiệm thành phần của bạn trong sự cô lập nữa.

Hãy xem demo trong app/app.component.spec.ts của chúng. Lấy thử nghiệm/router-stubs.ts và thêm vào dự án của bạn. Sau đó, bạn sẽ tiêm 2 mục được stubbed vào các khai báo TestBed của bạn.

+0

Cảm ơn bạn, tôi đánh giá cao sự tham chiếu đến các tài liệu trong câu trả lời của bạn – Bhetzie

+0

Thêm bài kiểm tra đơn vị làm việc của tôi, hy vọng có thể giúp đỡ người khác nếu họ đang gặp khó khăn. Cảm ơn một lần nữa! – Bhetzie

+0

Tôi không hiểu tại sao những sơ đồ này không giao hàng trong/master – FlavorScape

Các vấn đề liên quan