Угловые 2-х модульные компоненты тестирования с routerLink
Я пытаюсь протестировать свой компонент с помощью 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);
});
});
Я просмотрел несколько ответов на похожие вопросы, но не смог найти решение, которое бы сработало для меня.
4 ответа
Вам необходимо настроить все маршруты. Для тестирования, а не с помощью 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');
Если вы не тестируете вещи, связанные с маршрутизатором, вы можете настроить тест на игнорирование неизвестных директив с помощью NO_ERRORS_SCHEMA.
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
Тот тест на наличие ссылки.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); });
Как проверить, что маршрутизатор действительно инициировал изменение 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');
}));