Как я могу протестировать routerLinkActive в автономном компоненте?
Если у меня есть неавтономный компонент следующим образом:
import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'sb-index',
template: `
<a [routerLink]="['routeA']" [routerLinkActive]="'active'">A</a>
<a [routerLink]="['routeB']" [routerLinkActive]="'active'">B</a>
`
})
export class IndexComponent {
}
Я могу протестировать следующую спецификацию, как показано в вопросе SO :
import { Component, NgZone } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Router, RouterLinkActive } from '@angular/router';
import { IndexComponent } from './index.component';
import { RouterTestingModule } from '@angular/router/testing';
@Component({
selector: 'sb-stub'
})
class StubComponent {}
describe('IndexComponent', () => {
let fixture: ComponentFixture<IndexComponent>;
let component: IndexComponent;
beforeEach(() => {
TestBed
.configureTestingModule({
declarations: [
IndexComponent,
StubComponent
],
imports: [
RouterTestingModule.withRoutes([
{ path: 'routeA', component: StubComponent },
{ path: 'routeB', component: StubComponent }
])
]
})
.compileComponents();
fixture = TestBed.createComponent(IndexComponent);
component = fixture.componentInstance;
});
it('should show "A" route as active', fakeAsync(() => {
fixture.detectChanges();
TestBed.inject(NgZone).run(() => {
TestBed.inject(Router).navigate(['routeA']);
tick();
fixture.detectChanges();
fixture.debugElement
.queryAll(By.directive(RouterLinkActive))
.map(debugElement => debugElement.nativeElement as HTMLAnchorElement)
.forEach(nativeElement => {
if (nativeElement.textContent === 'A') {
expect(nativeElement.classList.contains('active')).toBeTrue();
} else {
expect(nativeElement.classList.contains('active')).toBeFalse();
}
});
});
}));
});
Я не могу понять, как настроить те же тесты, если я изменюIndexComponent
быть отдельным компонентом следующим образом:
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterLink, RouterLinkActive, RouterModule, RouterOutlet } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'sb-index',
standalone: true,
template: `
<a [routerLink]="['routeA']" [routerLinkActive]="'active'">A</a>
<a [routerLink]="['routeB']" [routerLinkActive]="'active'">B</a>
`,
imports: [ RouterLink, RouterLinkActive, RouterOutlet ]
})
export class IndexComponent {
}
Я пробовал несколько разных вещей, в основном сосредоточившись на аспектах инъекции и области видимости, поскольку я предполагаю, что это изменилось следующим образом:
import { Component, EnvironmentInjector, NgZone } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { provideRouter, Router, RouterLinkActive, RouterOutlet } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { RouterLinkDirectiveStub } from '@sb/testing';
import { IndexComponent } from './index.component';
@Component({
standalone: true,
selector: 'sb-stub'
})
class StubComponent {}
describe('IndexComponent', () => {
let fixture: ComponentFixture<IndexComponent>;
let component: IndexComponent;
beforeEach(() => {
TestBed
.configureTestingModule({
imports: [
IndexComponent,
StubComponent
],
providers: [
provideRouter([
{ path: 'routeA', component: StubComponent },
{ path: 'routeB', component: StubComponent }
])
]
})
.overrideComponent(
IndexComponent,
{
set: {
imports: [ RouterOutlet, RouterLinkActive, RouterLinkDirectiveStub ]
}
}
)
.compileComponents();
fixture = TestBed.createComponent(IndexComponent);
component = fixture.componentInstance;
});
it('should show "A" route as active', fakeAsync(() => {
fixture.detectChanges();
fixture.ngZone?.run(() => {
fixture.componentRef.injector.get(Router).navigate(['routeA']);
// TestBed.inject(NgZone).run(() => {
// TestBed.inject(EnvironmentInjector).get(NgZone).run(() => {
// TestBed.inject(Router).navigate(['routeA']);
// TestBed.inject(EnvironmentInjector).get(Router).navigate(['routeA']);
// TestBed.platform.injector.get(Router).navigate(['routeA']);
tick();
fixture.detectChanges();
fixture.debugElement
.queryAll(By.directive(RouterLinkActive))
.map(debugElement => debugElement.nativeElement as HTMLAnchorElement)
.forEach(nativeElement => {
if (nativeElement.textContent === 'A') {
expect(nativeElement.classList.contains('active')).toBeTrue();
} else {
expect(nativeElement.classList.contains('active')).toBeFalse();
}
});
});
}));
});
Почти все они дают мне сообщение: IndexComponent должен показывать маршрут «A» как активный. FAILED Ожидается, что false будет истинным.
С помощью отладки я вижу, что тесты находят элементы сRouterLinkActive
директива, но маршрутизация, которая выполняется в начале тестового метода, похоже, не влияет на routerLinkActive, поэтому ни один из элементов не получает класс «активный».
Есть ли способ протестировать
routerLinkActive
элементы внутри автономного компонента?