I am trying to learn how to set up a Unit test using Jasmine and Angular 2 with Async. I have a component which calls a service. But I seem to hit a road block. I have a service like below: item.service.ts
import { Injectable } from "@angular/core";
import { Http, Response } from "@angular/http";
import { Observable } from "rxjs/Observable";
import { Item } from "./item";
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Injectable()
export class ItemService {
private baseUrl = 'api/items/'; // web api URL
constructor(private http: Http) { }
// calls the [GET] /api/items/GetLatest/{n} Web API method to retrieve the latest items.
getLatest(num?: number) {
let url = this.baseUrl + 'GetLatest/';
if (num != null) { url += num; }
return this.http.get(url)
.map(response => response.json())
.catch(this.handleError);
}
}
I am calling the service in a component (item-list.component.ts) as below:
import { Component, OnInit } from '@angular/core';
import { Item } from './item';
import { ItemService } from './item.service';
import { GridModule } from '@progress/kendo-angular-grid';
import { GroupDescriptor, process } from '@progress/kendo-data-query';
import { SortDescriptor, orderBy } from '@progress/kendo-data-query';
import { GridDataResult } from '@progress/kendo-angular-grid';
import '@telerik/kendo-theme-default/dist/all.css';
@Component({
selector: 'itemlist',
templateUrl: 'someItems.component.html',
})
export class ItemListComponent implements OnInit {
selectedItem: Item;
items: Item[];
errorMessage: string;
groups: GroupDescriptor[];
sort: SortDescriptor[] = [];
gridView: GridDataResult;
constructor(private itemService: ItemService) { }
ngOnInit() {
this.getLatest();
}
getLatest() {
this.itemService.getLatest(5)
.subscribe(latestItems => {
console.log(latestItems);
this.items = latestItems;
this.gridView = {
data: orderBy(this.items, this.sort),
total: this.items.length
};
}, error => {
console.log('error');
this.errorMessage = <any>error;
});
}
}
This is my item.component.spec.ts file
import { async, inject, ComponentFixture, TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ItemListComponent } from '../App/item-list.component';
import { ItemService } from '../App/item.service';
import { GridModule } from '@progress/kendo-angular-grid';
import { HttpModule, Http } from "@angular/http";
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/observable/of';
class MockMyService {
public items: Array<any>;
public getLatest(num?: number) {
this.items = [{ Id: 1, Title: "test1", Description: "test12" }]
return Observable.of(this.items);
}
}
describe('Component:ItemList', () => {
let fixture: ComponentFixture<ItemListComponent>;
let itemService: MockMyService;
describe('Async', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
ItemListComponent
],
providers: [
//ItemService
{ provide: ItemService, useClass: MockMyService }
],
imports: [
GridModule,HttpModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
fixture = TestBed.createComponent(ItemListComponent);
itemService = fixture.debugElement.injector.get(ItemService);
spyOn(itemService, 'getLatest')
.and.returnValue({ subscribe: () => { itemService.items} });
fixture.detectChanges();
}));
afterEach(() => {
fixture = undefined;//teardown
});
it('should get items', () => {
itemService.getLatest();
expect(fixture.debugElement.componentInstance.items.length).toEqual(1);
});
});
});
But the test throws error as below - Chrome 57.0.2987 (Windows 7 0.0.0) Component:ItemList Async should get items FAILED TypeError: Cannot read property 'length' of undefined I will really appreciate if anyone can help me out..