Ошибка: InvalidPipeArgument: 'function () { return fn.apply(this, arguments); }' для канала 'AsyncPipe' Модульное тестирование Angular 7

Я пишу модульные тестовые примеры в Angular 7, в этом процессе застрял, чтобы создать модуль проверка служебной переменной isLoading.

вот мой html-файл компонента приложения:

<router-outlet></router-outlet>


<div *ngIf = "guestUserService.isLoading | async"  class = "loaderdiv">
  <mat-spinner class = "loader"></mat-spinner>
</div> 

Сервисный файл:

export class GuestUserService {

  public isLoading: any = new BehaviorSubject(false);

}

Пример модульного теста:

 fdescribe('AppComponent', () => {
         let guestUserService: any;
         let guestUserServiceSpy: any;

          beforeEach(async(() => {
            guestUserService = jasmine.createSpyObj('GuestUserService', ['isLoading']);
            TestBed.configureTestingModule({
              providers: [
                { provide: GuestUserService, useValue: guestUserService }]
            }).compileComponents();
}));

 it('should render loader if isLoading true', () => {
    guestUserServiceSpy = guestUserService.isLoading.and.returnValue(true);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(guestUserService).toBeDefined();
    expect(guestUserServiceSpy).toBeDefined();
    expect(guestUserService.isLoading).toBeTruthy();
    expect(fixture.debugElement.query(By.css('.loader'))).toBeDefined();
    expect(compiled.querySelector('mat-spinner')).toBeTruthy();
  });

Получение ошибки:

Error: InvalidPipeArgument: 'function () { return fn.apply(this, arguments); }' for pipe 'AsyncPipe'

Есть ли правильный способ создать модульный тестовый пример для такого типа сценариев.

Тестирование функциональных 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
2
0
1 540
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Есть несколько проблем.

Во-первых, вы стреляете себе в ногу, используя тип any. Делая это, компилятор позволяет вам делать вещи, которые не имеют смысла. И вы также затрудняете чтение кода для себя. Свойство isLoading должно быть Observable<boolean>, так как это то, что ожидает шаблон. Так что используйте этот правильный тип вместо any.

Во-вторых, эта строка:

jasmine.createSpyObj('GuestUserService', ['isLoading'])

создает объект с функция с именем isLoading. Но у вашего фактического сервиса есть property of typeObservable`` с именем isLoading, и это то, что ожидает ваш шаблон, отсюда и ошибка: асинхронному каналу нужен наблюдаемый объект в качестве входных данных, но вы передаете его isLoading, который является функцией в вашем тесте, и не наблюдаемый (посмотрите, как использование правильного типа помогает рассуждать об ошибках, которые вы получаете?).

Кстати, эта функция возвращает логическое значение true вместо Observable<boolean>

Вы можете определить простой объект вместо использования jasmine для создания своего поддельного сервиса:

const fakeService = {
    isLoading: of(true)
}

Или вы можете использовать жасмин, но использовать его функцию spyOnProperty.

Или вы можете использовать BehaviorSubject<boolean> как тип isLoading и, таким образом, использовать реальную реализацию службы и просто заставить объект излучать true.

спасибо, id тот же, вернул функцию вместо свойства

J King 31.03.2021 18:27

Немного дополнительной информации о создании объектов-шпионов Jasmine для поддельных сервисов со свойствами получения.

Чтобы создать шпионский объект с get-свойствами, методы и свойства нужно передать в конструктор отдельно:

createSpyObj('ExampleService’, { methods }, { get properties }); 

Пример

Следующая служба «Пример» имеет два метода и два свойства получения:

export class ExampleService {
  // properties
  public get exampleProperty1(): Observable<boolean> {
    // implementation...
  }
  public get exampleProperty2(): Observable<Number> {
    // implementation...
  }

  // methods
  public exampleMethod1(): void {
    // implementation...
  }
  public exampleMethod2(): void {
    // implementation...
  }
}

Создайте шпионский объект Jasmine для примерного сервиса следующим образом:

fakeExampleService = jasmine.createSpyObj<ExampleService>(
  'FakeExampleService',
  {
    // pass in the methods here...
    exampleMethod1: undefined,
    exampleMethod2: undefined
  },
  {
    // pass in the properties here...
    exampleProperty1: of(false),
    exampleProperty2: of(1),
  }
);

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