带routerLink的Angular 2单元测试组件

带routerLink的Angular 2单元测试组件,angular,typescript,angular2-routing,angular2-testing,Angular,Typescript,Angular2 Routing,Angular2 Testing,我试图用angular 2 final测试我的组件,但是我得到了一个错误,因为组件使用了routerLink指令。我得到以下错误: 无法绑定到“routerLink”,因为它不是“a”的已知属性 这是ListComponent模板的相关代码 <a *ngFor="let item of data.list" class="box" routerLink="/settings/{{collectionName}}/edit/{{item._id}}"> 我查看了几个类

我试图用angular 2 final测试我的组件,但是我得到了一个错误,因为组件使用了
routerLink
指令。我得到以下错误:

无法绑定到“routerLink”,因为它不是“a”的已知属性

这是
ListComponent
模板的相关代码

<a 
  *ngFor="let item of data.list" 
  class="box"
  routerLink="/settings/{{collectionName}}/edit/{{item._id}}">

我查看了几个类似问题的答案,但没有找到适合我的解决方案。

您需要配置所有路由。对于测试,您可以使用
@angular/router/testing
中的
RouterTestingModule
,而不是使用
RouterModule
,在这里您可以设置一些模拟路由。您还需要从
@angular/common
为您的
*ngFor
导入
CommonModule
。下面是一个完整的通过测试

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { By } from '@angular/platform-browser';
import { Location, CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, inject, async } from '@angular/core/testing';

@Component({
  template: `
    <a routerLink="/settings/{{collName}}/edit/{{item._id}}">link</a>
    <router-outlet></router-outlet>
  `
})
class TestComponent {
  collName = 'testing';
  item = {
    _id: 1
  };
}

@Component({
  template: ''
})
class DummyComponent {
}

describe('component: TestComponent', function () {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        CommonModule,
        RouterTestingModule.withRoutes([
         { path: 'settings/:collection/edit/:item', component: DummyComponent }
        ])
      ],
      declarations: [ TestComponent, DummyComponent ]
    });
  });

  it('should go to url',
    async(inject([Router, Location], (router: Router, location: Location) => {

    let fixture = TestBed.createComponent(TestComponent);
    fixture.detectChanges();

    fixture.debugElement.query(By.css('a')).nativeElement.click();
    fixture.whenStable().then(() => {
      expect(location.path()).toEqual('/settings/testing/edit/1');
      console.log('after expect');
    });
  })));
});
然后只需检查链接是否以正确的URL路径呈现,例如

let href = fixture.debugElement.query(By.css('a')).nativeElement
    .getAttribute('href');
expect(href).toEqual('/settings/testing/edit/1');

如果您没有测试路由器相关的东西,您可以将测试配置为忽略带有“无错误”模式的未知指令

 import { NO_ERRORS_SCHEMA } from '@angular/core';
 TestBed.configureTestingModule({
   declarations: [
     ListComponent,
   ],
   schemas: [ NO_ERRORS_SCHEMA ]
 });

routerLink
编写测试用例。您可以按照以下步骤操作

  • 导入
    RouterTestingModule
    RouterLinkWithHref

    import { RouterTestingModule } from '@angular/router/testing';
    import { RouterLinkWithHref } from '@angular/router';
    
  • 在模块中导入
    RouterTestingModule

    TestBed.configureTestingModule({
      imports: [ RouterTestingModule.withRoutes([])],
      declarations: [ TestingComponent ]
    })
    
  • 在测试用例中,找到指令
    RouterLinkWithHref
    tot测试链接是否存在

    it('should have a link to /', () => {
      const debugElements = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
      const index = debugElements.findIndex(de => {
        return de.properties['href'] === '/';
      });
      expect(index).toBeGreaterThan(-1);
    });
    

  • 谢谢,这已经很有帮助了,但是我不能让单元测试失败。似乎因为
    async
    这个块中的所有内容都被GINOR。我试图向
    it(“…”,(done)=>{async(…done())}添加一个done函数
    但是后来我从测试中得到了
    错误:Timeout
    。糟糕的是,我把
    async
    包装在另一个函数中,而不是作为
    它的第二个参数。它现在可以工作了,谢谢。这太棒了。终于找到了一个适用于2.0 Final的答案(我使用的是2.1)!因为我在很多测试中都需要相同的配置,所以我创建了一个只测试的模块,该模块配置了RouterTestingModule并声明了DummyComponent。然后我将该模块和DummyComponent放入一个测试/子文件夹,然后我可以将其导入到我的任何单元测试中。如果您只需要渲染route,请使用@PeeskilletrLink您不必设置路由非常彻底和可靠的答案,谢谢。解决了我看到的所有路由链接测试问题。感谢这是我问题的一个更具体的解决方案,尽管我从第一个问题中学到了这一点。请您也分享从何处导入
    无错误模式
    无错误模式
    是最新的作为
    实验性的
    @CalvinDale,这不重要。很多东西都被标记为实验性的(包括常用的类,如Http)。导入也作为
    导入:[RouterTestingModule]
    TestBed.configureTestingModule({
      imports: [ RouterTestingModule.withRoutes([])],
      declarations: [ TestingComponent ]
    })
    
    it('should have a link to /', () => {
      const debugElements = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
      const index = debugElements.findIndex(de => {
        return de.properties['href'] === '/';
      });
      expect(index).toBeGreaterThan(-1);
    });