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:

https://this-is-angular.github.io/angular-guides/docs/standalone-apis/configuring-the-router-using-standalone-features#configuring-the-router-for-component-tests

Надеюсь это поможет!

Другие вопросы по тегам