Имитационный импорт лениво загруженного автономного компонента

У меня есть компонент, который представляет собой кнопку, которая при нажатии будет лениво импортировать автономный компонент, а затем передавать его службе, которая будет создана внутри заполнителя ng-template.

Метод, вызываемый при нажатии кнопки, выглядит следующим образом:

  protected async toggleHelpDrawer(): Promise<void> {
    await import('@myorg/shared-feature-help').then(ref => {
      (this._drawerEvents.drawerOpen && this._drawerEvents.drawerType === this.drawerType)
        ? this._drawerEvents.closeDrawer()
        : this._drawerEvents.openDrawer(ref.HelpComponent, this.drawerType);
    });
  }

Я пытаюсь создать модульный тест для этого компонента, который будет издеваться над методами DrawerEventsService и шпионить за методами openDrawer и closeDrawer.

Проблема, с которой я столкнулся, заключается в том, что внутри HelpComponent есть такие элементы, как @ViewChild и импорт Router. При запуске модульного теста я получаю ошибки о том, что эти атрибуты не определены и т. д.

Я хочу использовать ng-mocks, чтобы просто издеваться над HelpComponent, однако я не знаю, как имитировать компонент, возвращаемый в результате динамического импорта, и мне не удалось найти примеры в Интернете.

Итак, есть ли какой-нибудь способ с помощью TestBed гарантировать, что значение, возвращаемое из моего async import, имеет тип MockComponent(HelpComponent)?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете импортировать весь модуль, а затем использовать spyOnProperty, чтобы изменить возвращаемое значение свойства.

import * as sharedFeatureHelp from "@myorg/shared-feature-help";
...

...
beforeEach(() => {
    ...
    spyOnProperty(sharedFeatureHelp, "HelpComponent").and.returnValue({} as any);
    ...

});
...

К сожалению, ваше решение мне не подошло, поскольку оно вводит явную зависимость от HelpComponent через ваш оператор импорта. Я опубликовал ответ и решение, полученное от ChatGPT.

Cody Pritchard 11.06.2024 02:15
Ответ принят как подходящий

Согласно

В моем файле test-setup.ts я могу имитировать оператор импорта следующим образом:

jest.spyOn(MockService(DrawerEventsService), 'openDrawer');
jest.spyOn(MockService(DrawerEventsService), 'closeDrawer');

jest.mock('@myorg/shared-feature-help', () => {
  return {
    __esModule: true,
    HelpComponent: () => 'MockedHelpComponent'
  };
});

Целью было имитировать сам оператор динамического импорта, не вводя каких-либо явных зависимостей к HelpComponent.

Насколько я понимаю, это решение имитирует команду import, так что значение ref.HelpComponent представляет собой строку, а не фактический компонент.

И это работает, потому что мой метод openDrawer() имеет тип

openDrawer(component: Type<unknown>, type: DrawerTypes): void {
  this._drawerType$.next(type);
  this._drawerContainer?.createComponent(component);
}

Это позволяет мне теперь правильно отслеживать метод openDrawer и проверять, что он был вызван один раз, как и ожидалось.

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