0

I am a newbie to Angular 2 and Karma + Jasmine unit tests. I cannot figure out what semantic error I have made in order to make this unit test use the mocked response. In the console, when "expect(items[0].itemId).toBe(2);" is run, it says items[0].itemId is undefined.

Would someone be able to help me out or point me in the right direction? Please let me know if you need any additional information. Thanks!

item.ts

export class Item {
     itemId: number;
     itemName: string;
     itemDescription: string;
}

item.service.ts

import { Injectable, Inject } from '@angular/core';
    import { Headers, Http } from '@angular/http';
    import { Observable } from 'rxjs/Rx';
    import { Item } from './item';
@Injectable()
export class ItemService {
    private headers = new Headers({'Content-Type': 'application/json'});

    constructor(
    private http: Http)
    {

    }

    getItems(listOptions: Object): Observable<Item[]> {
    return this.http.post('/listItems', listOptions, {headers:this.headers})
       .map(response => response.json() as Item[])
  }
}

item.service.spec.ts

import { TestBed, fakeAsync, inject, tick } from '@angular/core/testing';
import { MockBackend } from '@angular/http/testing';
import { Http, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { ItemService } from './item.service';
import { Item } from './item';


describe('ItemService', () => {
  let mockResponse, matchingItem, connection;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        ItemService,
        MockBackend,
        BaseRequestOptions,
        {
          provide: Http,
          useFactory: (backend, defaultOptions) => new Http(backend, defaultOptions),
          deps: [MockBackend, BaseRequestOptions]
        },
        // { provide: XHRBackend, useClass: MockBackend }        
      ]
    });

    const items = [
      {
        "itemId":2,
        "itemName":"test item1",
        "itemDescription":"hello hello"        
      },
      {
        "itemId":1,
        "itemName":"name2124111121",
        "itemDescription":"description212412112"        
      }
    ];
    mockResponse = new Response(new ResponseOptions({body: {data: items}, status: 200}));
  });

  describe('getItems', () => {

    //Subscribing to the connection and storing it for later
    it('should return all the items',inject([ItemService, MockBackend], (service: ItemService, backend: MockBackend) => {

        backend.connections.subscribe(connection => {
          connection.mockRespond(mockResponse);
        });
        service.getItems({isActive: true, sortColumn: "lastModifiedDateUtc", sortOrder: "desc"})
        .subscribe((items: Item[]) => {
          expect(items.length).toBe(2);
        });
      }));
    });
  });

Plunkr: https://plnkr.co/edit/m7In2eVh6oXu8VNYFf9l?p=preview (There are some errors with the Plunkr I need help with as well but the main files are there)

user3495469
  • 139
  • 2
  • 11
  • 1
    `response.json()` isn't the array of items, `response.json().data` is. – jonrsharpe Mar 03 '17 at 16:22
  • @jonrsharpe Thanks! I get an error that says `Property 'data' does not exist on type 'Item[]'` – user3495469 Mar 03 '17 at 16:25
  • Yes, because you've used the wrong type for the argument. – jonrsharpe Mar 03 '17 at 16:38
  • @jonrsharpe could you tell me what type I should use? – user3495469 Mar 03 '17 at 17:37
  • The one that reflects *the actual object you're sending*? In this case, something that has a field named `data` which contains the item array. If that's different than the actual payload, fix your test to reflect the real structure. – jonrsharpe Mar 03 '17 at 17:38
  • took me a little while to understand your solution but realized after talking to a co-worker this is where my error was: `mockResponse = new Response(new ResponseOptions({body: {data: items}, status: 200}));` should be `mockResponse = new Response(new ResponseOptions({body: items, status: 200}));` Thanks for your assistance! – user3495469 Mar 06 '17 at 15:55

1 Answers1

0

The mockResponse body did not match the actual response body, that is why I was getting the error.

mockResponse = new Response(new ResponseOptions({body: {data: items}, status: 200})); should be mockResponse = new Response(new ResponseOptions({body: items, status: 200}));

user3495469
  • 139
  • 2
  • 11