Почему expect(component['numberHogeNames']()).toBe(3)
не проходит мой тест Angular?
Вот упрощенная версия моего кода:
// hoge-service.ts
interface HogeData {
id: string;
name: string;
}
export class HogeService {
private dataSrc = signal<HogeData[]>([
{ id: '1', name: 'kage' },
{ id: '2', name: 'sage' },
{ id: '3', name: 'tage' },
{ id: '4', name: 'nage' },
{ id: '5', name: 'mage' },
{ id: '6', name: 'yage' },
...
]);
numberHogeNames = computed<number>(() => {
return this.dataSrc().filter((item) => item.name === 'hoge').length;
});
}
// hoge-component.ts
@Component({
standalone: true,
providers: [HogeService],
template: `<div class = "num">{{ numberHogeNames() }}</div>`,
encapsulation: ViewEncapsulation.Emulated,
changeDetection: ChangeDetectionStrategy.OnPush,
...
})
export class HogeComponent {
private hogeService = inject(HogeService);
protected numberHogeNames = computed<number>(() => {
return this.hogeService.numberHogeNames();
});
}
// hoge-component.spec.ts
describe('Hoge Test', () => {
let component: HogeComponent;
let fixture: ComponentFixture<HogeComponent>;
let hogeService: HogeService;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HogeComponent],
providers: [HogeService],
}).compileComponents();
fixture = TestBed.createComponent(HogeComponent);
component = fixture.componentInstance;
hogeService = TestBed.inject(HogeService);
});
it('Case 01', async () => {
hogeService['dataSrc'].update((current) => {
current.forEach((item, index) => {
if (index < 3) item.name = 'hoge';
});
return [...current];
});
// Success
expect(hogeService.numberHogeNames()).toBe(3);
fixture.detectChanges();
// Failed (Expected 0 to be 3.)
expect(component['numberHogeNames']()).toBe(3);
})
});
Несмотря на провал теста, компонент работает корректно при использовании в реальном приложении. Значение numberHogeNames
на экране обновляется, как и ожидалось, при изменении dataSrc
.
Я попытался изменить частный сигнал dataSrc
в HogeService
, используя update()
, чтобы изменить свойства name
некоторых элементов на hoge
. После обновления dataSrc
я ожидал, что hogeService.numberHogeNames()
и component['numberHogeNames']()
вернутся 3
, поскольку есть три элемента с именем hoge
.
В тесте hogeService.numberHogeNames()
корректно обновляется до 3
, что является ожидаемым поведением. Однако component['numberHogeNames']()
по-прежнему возвращает старое значение и не обновляется должным образом.
Я пробовал использовать fixture.detectChanges()
и ждать небольшой задержки с помощью setTimeout
, чтобы посмотреть, обновится ли вычисленный сигнал компонента, но эти попытки не решили проблему.
Я ожидаю, что вычисленный сигнал компонента (numberHogeNames
) будет отражать изменения сигнала службы (dataSrc
) так же, как это происходит в реальном приложении, где все работает так, как задумано.
@BennyHalperin Я пробовал изменить numberHogeNames
с protected
на public
и получил к нему доступ напрямую с помощью component.numberHogeNames()
, но проблема все еще сохраняется.
Вам необходимо сослаться на сервис, который внедрен в компонент (т.е. component.hogeService)
:
component.hogeService['dataSrc'].update((current) => {
current.forEach((item, index) => {
if (index < 3) item.name = 'hoge';
});
return [...current];
});
Потом позже:
expect(component.hogeService.numberHogeNames()).toBe(3);
Тест после этих изменений должен пройти.
Тест прошел успешно! Поскольку это проверка HogeComponent
, корректно манипулировать dataSrc
из компонента. Большое спасибо за вашу помощь!
Всегда пожалуйста. Мне потребовалось некоторое время, чтобы это понять 😊
Буду признателен за одобрение моего ответа и повышение. Спасибо.
Что, если вы измените его с
protected
наpublic
и получите к нему доступcomponent.numberHogeNames()
?