I am trying to test my component. The components receives an observable string and object as an input and iterates over this object and makes some calculations.
The component works fine in a browser, but throws an error when I execute the unit test:
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)
So i’ve started simplifying the component but still don't understand why the tests are failing.
My component's template:
<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;
});
}
}
My unit test:
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('');
});
});
});
It's hard to understand where the problem since unit tests fails with timeout, but I noticed if I remove <div *ngIf="hasDestinationFilter"></div> or <div *ngFor="let shipment of (filteredShipments$ | async)"></div> from my templates the tests doesn't fail with timeout. Where can be my mistake?