Angular组件的测试因超时而失败

时间:2018-03-18 11:15:15

标签: javascript angular unit-testing karma-runner karma-jasmine

我正在尝试测试我的组件。组件接收一个可观察的字符串和对象作为输入,并迭代该对象并进行一些计算。

该组件在浏览器中正常工作,但在执行单元测试时会抛出错误:

Chrome 65.0.3325 (Mac OS X 10.13.1) ERROR
  Disconnected, because no message in 10000 ms.
Chrome 65.0.3325 (Mac OS X 10.13.1): Executed 1 of 116 DISCONNECTED (10.136 secs / 0.092 secs)
Chrome 65.0.3325 (Mac OS X 10.13.1) ERROR
Chrome 65.0.3325 (Mac OS X 10.13.1): Executed 1 of 116 DISCONNECTED (10.136 secs / 0.092 secs)

所以我开始简化组件,但仍然不明白测试失败的原因。

我的组件模板:

<div *ngIf="hasDestinationFilter"></div>

<div *ngFor="let shipment of (filteredShipments$ | async)"></div>

打字稿:

import { Component, Input, OnInit } from '@angular/core';

import { Observable } from 'rxjs/Observable';

import 'rxjs/add/observable/combineLatest';
import 'rxjs/add/operator/map';

import { ShipmentFilterService } from '../../services/shipment-filter/shipment-filter.service';

@Component({
  selector: 'search-results',
  templateUrl: './search-results.component.html',
})
export class SearchResultsComponent implements OnInit {
  @Input() searchResults$: Observable<any>;
  @Input() destination$: Observable<string>;

  filteredShipments$: Observable<any[]>;
  hasDestinationFilter = false;

  constructor(private shipmentFilterService: ShipmentFilterService) {}

  ngOnInit() {
    this.filteredShipments$ = Observable
      .combineLatest(this.searchResults$, this.destination$)
      .map(([ { shipments }, destination ]) => {
        this.hasDestinationFilter = this.shipmentFilterService.hasDestinationFilter(shipments);

        if (this.hasDestinationFilter) {
          return shipments;
        }
        return shipments;
      });
  }
}

我的单元测试:

import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { Observable } from 'rxjs/Observable';

import { ShipmentFilterService } from '../../services/shipment-filter/shipment-filter.service';
import { SearchResultsComponent } from './search-results.component';

describe('SearchResultsComponent', () => {
  let mockedHasDestinationFilter;

  const mockedShipment = {
    collectedDate: null,
    collectionCity: null,
    collectionDate: null,
    consignmentKey: null,
    consignmentNumber: null,
    customerReference: null,
    deliveryDueDate: null,
    deliveryTown: null,
    destinationCountry: null,
    fedexNumber: null,
    fromDate: null,
    originCountry: null,
    pieceQuantity: null,
    podFound: null,
    revisedDeliveryDate: null,
    shipmentId: null,
    signatory: null,
    signatoryFound: false,
    statusData: [],
    toDate: null,
    trackId: null,
  };

  const shipmentFilterServiceStub = {
    hasDestinationFilter: () => mockedHasDestinationFilter,
  };

  beforeEach(async(() => {
    TestBed
      .configureTestingModule({
        declarations: [
          SearchResultsComponent,
        ],
        providers: [
          { provide: ShipmentFilterService, useValue: shipmentFilterServiceStub },
        ],
        schemas: [
          NO_ERRORS_SCHEMA,
        ],
      })
      .compileComponents();
  }));

  function getComponent(destination = null) {
    let component: SearchResultsComponent;
    let fixture: ComponentFixture<SearchResultsComponent>;

    fixture = TestBed.createComponent(SearchResultsComponent);
    component = fixture.componentInstance;

    component.searchResults$ = Observable.of({
      query: {
        input: 'abc123',
      },
      shipments: [
        mockedShipment,
        mockedShipment,
        mockedShipment,
        mockedShipment,
        mockedShipment,
      ],
    });
    component.destination$ = Observable.of(destination);
    fixture.detectChanges();

    return fixture;
  }

  describe('optionally filters shipments by destination', () => {
    it('shows all shipments when there is no destination filter', () => {
      mockedHasDestinationFilter = false;
      const component = getComponent();

      expect(component.debugElement.queryAll(By.css('pb-shipment')).length).toBe(5);
    });

    fit('shows all shipments when there is destination filter, but no destination has been chosen', () => {
      mockedHasDestinationFilter = true;
      const component = getComponent('');
    });
  });
});

很难理解单元测试因超时而失败的问题,但我注意到如果从模板中删除<div *ngIf="hasDestinationFilter"></div><div *ngFor="let shipment of (filteredShipments$ | async)"></div>,则测试不会失败超时。哪里可能是我的错?

1 个答案:

答案 0 :(得分:1)

尝试使用默认值

初始化输入值

@Input() searchResults$: Observable<any> = Observable.from("");
@Input() destination$: Observable<string> = Observable.from("");