使用 routerLink 进行 Angular 2 单元测试组件

问题描述 投票:0回答:4

我正在尝试使用 Angular 2 Final 测试我的组件,但出现错误,因为该组件使用

routerLink
指令。我收到以下错误:

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

这是

ListComponent
模板的相关代码

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

这是我的测试。

import { TestBed } from '@angular/core/testing';

import { ListComponent } from './list.component';
import { defaultData, collectionName } from '../../config';
import { initialState } from '../../reducers/reducer';


const data = {
  sort: initialState.sort,
  list: [defaultData, defaultData],
};

describe(`${collectionName} ListComponent`, () => {
  let fixture;
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        ListComponent,
      ],
    }).compileComponents(); // compile template and css;
    fixture = TestBed.createComponent(ListComponent);
    fixture.componentInstance.data = data;
    fixture.detectChanges();
  });

  it('should render 2 items in list', () => {
    const el = fixture.debugElement.nativeElement;
    expect(el.querySelectorAll('.box').length).toBe(3);
  });
});

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

angular typescript angular2-routing angular2-testing
4个回答
130
投票

您需要配置所有路由。为了进行测试,您可以使用

RouterModule
中的
RouterTestingModule
,而不是使用
@angular/router/testing
,您可以在其中设置一些模拟路线。您还需要从
CommonModule
为您的
@angular/common
导入
*ngFor
。以下是完整的通过测试

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');
    });
  })));
});

更新

另一个选项,如果您只想测试路线是否正确呈现,而不尝试导航...

您只需导入

RouterTestingModule
,无需配置任何路由

imports: [ RouterTestingModule ]

然后只需检查链接是否使用正确的 URL 路径呈现,例如

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

23
投票

如果您不测试路由器相关的内容,您可以将测试配置为忽略带有“NO_ERRORS_SCHEMA”的未知指令

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

12
投票

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

  1. 导入

    RouterTestingModule
    RouterLinkWithHref

    import { RouterTestingModule } from '@angular/router/testing';
    import { RouterLinkWithHref } from '@angular/router';
    
  2. 在您的模块中导入

    RouterTestingModule

    TestBed.configureTestingModule({
      imports: [ RouterTestingModule.withRoutes([])],
      declarations: [ TestingComponent ]
    })
    
  3. 在测试用例中找到指令

    RouterLinkWithHref
    来测试链接是否存在。

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

0
投票

如何检查路由器是否确实触发了 URL 更改


解决方案灵感来自 https://medium.com/@douglascaina/angular-tdd-how-to-test-routerlink-or-url-change-494f18208443


我的设置(使用

ng-mocks
):

class MockComponent {}

// ...

MockBuilder(MyComponent)
  .keep(RouterTestingModule.withRoutes([{ path: 'my/path', component: MockComponent }]))
  .keep(RouterLink)

我的测试用例:

it('when clicked, myLinkElement should lead to /my/path', fakeAsync(() => {
  const { page, router } = setup();
  page.detectChanges();

  page.click(page.myLinkElement().nativeElement);
  tick();

  expect(router.url).toEqual('/my/path');
}));
© www.soinside.com 2019 - 2024. All rights reserved.