Как устранить ошибку InvalidPipeArgument 'AsyncPipe' в модульном тестировании Angular? - PullRequest
1 голос
/ 03 августа 2020

Я получаю ошибку InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' в модульном тесте, когда использую канал | async в шаблоне.

Пытался решить эту проблему с помощью tick, fakeAsync and whenStable, но это не сработало.

Когда я удаляю часть | async в шаблоне, ошибка исчезает, и модульный тест работает, но на этот раз код не работает. Мне нужно использовать | async в шаблоне, чтобы код работал.

Как я могу решить эту InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' ошибку?

Шаблон:

<ngb-accordion  
    [closeOthers]="true"  
    [activeIds]="setActiveAcc()">
    <div *ngFor="let child of el?.children | async; let i = index">
        <ngb-panel id="{{(child?.value?.properties | async)?.style.includes('OpenAcc')}}-{{i}}">
            <ng-template ngbPanelHeader>
                <div class="d-flex align-items-center justify-content-between">
                    <button ngbPanelToggle class="btn btn-link container-fluid text-left">
                        {{ (child?.value?.properties | async)?.content}}
                    </button>
                </div>
            </ng-template>
            <ng-template ngbPanelContent>
                <tst-element [item]="child"></tst-element>
            </ng-template>
        </ngb-panel>
    </div>
</ngb-accordion>

Компонент:

export class AccComponent implements OnInit {
    constructor(
      public el: ItemModelTree
    ) {}

    @Input() childrens: Array<any> = [];

    ngOnInit() {
        this.el.children.pipe(
          mapObservableArray((children: ObservableTree<ItemModel>) => children.value.properties))
            .subscribe((props: Properties[]) => {
            this.childrens = props as any;
        });
    }

    setActiveAcc() {
        if (this.childrens.find((child: any) => child.style.includes('OpenAcc'))) {
          const activeAcc = this.childrens.findIndex((child: any) => child.style.includes('OpenAcc'));
          return 'true-' + activeAcc;
        } else {
            return 'false'
        }
    }
}

Модульный тест:

import { NO_ERRORS_SCHEMA } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { ItemModelTree } from './core';
import { AccComponent } from './accordion.component';
import { of } from 'rxjs';

describe('accardion component', () => {
  const itemModel = {
    value: {
      name: 'accordion'
    },
    children: [
      {
        id: 'acc-1',
        value: {
          properties: [
            {
              content: 'test',
              style: ['OpenAcc']
            }
          ]
        }
      }
    ],
  };
  const mockTree = jasmine.createSpyObj('el', itemModel);
  mockTree.children = of(itemModel.children);
  
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [],
      declarations: [AccComponent],
      providers: [
        { provide: ItemModelTree, useValue: mockTree }
      ],
      schemas: [NO_ERRORS_SCHEMA],
    }).compileComponents();
  });

  it('should set the activeAccordion to true', async () => {
    const fixture = TestBed.createComponent(AccComponent);
    const componentInst = fixture.componentInstance;

    (componentInst as any).tree = {
      children: of([
        {
          id: 'acc-1',
          value: {
            properties: [
              {
                label: 'test',
                styles: ['OpenAcc']
              }
            ]
          }
        }
      ])
    };

    fixture.detectChanges();
    
    
    expect(componentInst).toBeDefined();
    expect(componentInst.setActiveAcc()).toEqual('true-0');
  });
});

Как устранить ошибку InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' с помощью трубы | async?

1 Ответ

0 голосов
/ 03 августа 2020

Внутри itemModel mock нужно сделать properties: of(/* your data */) из-за этих строк в шаблоне: child?.value?.properties | async.

...