title: How to test a Angular 2 service used in a component using Jasmine
body: <p>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:
  <strong>item.service.ts</strong></p>
  
  <pre><code>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 =&gt; response.json())
              .catch(this.handleError);
      }
  }
  </code></pre>
  
  <p>I am calling the service in a component (<strong>item-list.component.ts</strong>) as below:</p>
  
  <pre><code>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 =&gt; {
                  console.log(latestItems);
                  this.items = latestItems;
                  this.gridView = {
                      data: orderBy(this.items, this.sort),
                      total: this.items.length
                  };
              }, error =&gt; {
                  console.log('error');
                  this.errorMessage = &lt;any&gt;error;
              });
      }   
  
  } 
  </code></pre>
  
  <p>This is my <strong>item.component.spec.ts</strong> file</p>
  
  <pre><code>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&lt;any&gt;;
      public getLatest(num?: number) {
          this.items = [{ Id: 1, Title: "test1", Description: "test12" }]
          return Observable.of(this.items);
  
      }
  }
  
  describe('Component:ItemList', () =&gt; {
      let fixture: ComponentFixture&lt;ItemListComponent&gt;;
      let itemService: MockMyService;
  
      describe('Async', () =&gt; {
          beforeEach(async(() =&gt; { 
              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: () =&gt; { itemService.items} });                     
  
              fixture.detectChanges();               
  
          }));
  
          afterEach(() =&gt; {
              fixture = undefined;//teardown
          });                             
  
          it('should get items', () =&gt; {
               itemService.getLatest();
               expect(fixture.debugElement.componentInstance.items.length).toEqual(1);
          });    
  
      });
  });
  </code></pre>
  
  <p>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..</p>