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

标签 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>

typescript :

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>从我的模板中,测试不会因超时而失败。我的错误在哪里?

最佳答案

尝试使用默认值初始化输入值

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

关于javascript - Angular 组件的测试因超时而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49347219/

相关文章:

javascript - 如何将 LoDash GroupBY 与不同的数组类型一起使用

angular - 自定义每个文件夹的 TypeScript 编译器选项

unit-testing - 如何模拟 LDAP Laravel 身份验证进行单元测试

javascript - 调用匹配按钮属性的函数

javascript - 在 Canvas 上移动元素

javascript - 使用 "show more"按钮隐藏列表项

javascript - 如何有一个开关,同时显示一开一关?

angular - 如何在 Angular 中包含本地库?

unit-testing - 如何验证 Purescript typeclass 法则?

javascript - 未定义不是函数: unit testing passport authentication custom callback