RouterTestingModule.withRoutes в тесте автономного компонента Angular
После перехода на автономные компоненты в Angular, как мы имитируем маршруты тестирования?
Рассмотрим компонент
@Component({
standalone: true,
imports: [RouterModule]
template: `<a [routerLink]="elsewhere"/>`,
})
class FooComponent {}
конфигурации теста, которые больше не работают...
beforeEach(() => {
TestBed.overrideComponent(FooComponent, {
set: {
//not possible because of type error
imports: [RouterTestingModule.withRoutes([...])],
},
}).configureTestingModule({
imports: [FooComponent],
});
});
beforeEach(() => {
TestBed.configureTestingModule({
//no effect, in my opinion component still imports the real RouterModule
imports: [FooComponent, RouterTestingModule.withRoutes([...])],
});
});
beforeEach(() => {
TestBed.overrideComponent(FooComponent, {
set: {
imports: [RouterTestingModule],
providers: [
provideRoutes([...]) //doesn't have any effect
],
},
}).configureTestingModule({
imports: [FooComponent],
});
});
beforeEach(() => {
TestBed.overrideComponent(FooComponent, {
set: {
imports: [],
providers: [
provideRouter([...]) //doesn't have any effect
],
},
}).configureTestingModule({
imports: [FooComponent],
});
});
у кого-нибудь есть рабочее решение для этого?
1 ответ
Я столкнулся с аналогичной проблемой, хотя моя связана с навигацией с помощью маршрутизатора. Чтобы смоделировать что-то вроде маршрутизатора, вы можете просто переопределить поставщика уровня компонента для маршрутизатора, как я делаю в своем тесте. Я использую библиотеку тестирования Angular, которая многое упрощает, но вы можете применить ее к самому компоненту, как вы делаете в своем примере переопределения компонента:
Тесты:
import { Router } from '@angular/router';
import { fireEvent, render, screen } from '@testing-library/angular';
import { FooComponent } from './foo.component';
describe('FooComponent', () => {
it('routes on click', async () => {
const routerSpy = jasmine.createSpyObj<Router>('Router', ['navigateByUrl']);
await render(FooComponent, { componentProviders: [{ provide: Router, useValue: routerSpy }]});
fireEvent.click(screen.getByRole('button', { name: 'Bar' }));
expect(routerSpy.navigateByUrl).toHaveBeenCalledOnceWith('/foo');
});
});
Фактический код:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
standalone: true,
template: '<button (click)="onBar()">Bar</button>'
})
export class FooComponent {
public constructor(private _router: Router) {}
public onBar() {
this._router.navigateByUrl('/foo');
}
}
Я понимаю, что это может отличаться от того, что вы пытаетесь выполнить, но в зависимости от того, что вы на самом деле пытаетесь протестировать, это может дать вам некоторое направление. Вместо того, чтобы тестировать реализацию, вы можете просто проверить, как вы взаимодействуете с фреймворком, как вы ожидаете. Если вам абсолютно необходимо отображать маршруты, я действительно нашел этот ресурс, который может вам подойти и не использует библиотеку тестирования angular:
Надеюсь это поможет!