Angular 2.0.0 - Ionic 2 RC0 - Npm 3.10.8 - Node v4.5.0 - Karma 1.3.0 - Jasmine 2.5.2
previous question: Angular 2 -- Mocking - No Provider for HTTP
I'm now getting a new error while executing npm test
: null is not an object (evaluating '_this.events.length')
Which is triggered by this code: if(this.events.length > 0){
in EventsPage which means my response I set in events.spec.ts
is somehow not properly returned.
I'm new to mocking Angular2 so it's moest likely a rookie mistake.
(changed some code from previous question, so I'll repost them)
EventPage
import { Component } from '@angular/core';
import { NavController, Loading, LoadingController } from 'ionic-angular';
import { APICaller } from '../../services/apicaller.service';
import { EventDetailComponent } from '../event-detail/event-detail.component';
import { Event } from '../../models/event.model';
/*
Class for Evenementen Overzicht.
*/
@Component({
selector: 'events-component',
templateUrl: 'events.component.html',
providers: [ APICaller ]
})
/** -------------------------------------------------------------------------------------- */
export class EventsPage {
//list of all events
public events : Array<Event>;
//the event that has been clicked on the page
public selectedEvent : Event;
//boolean to show 'no events' error message
public noEvents:boolean;
/** -------------------------------------------------------------------------------------- */
constructor(public navCtrl : NavController, public apiCaller:APICaller, public loadingCtrl : LoadingController) {
//retrieve all events --> async method, can't use this.events yet.
this.getEvents();
}
/** -------------------------------------------------------------------------------------- */
/**Get Events - Sets the 'events' variable to all events found by the API. */
getEvents(){
//setup a loadingscreen (broke testing so removed for now)
// let loading = this.loadingCtrl.create({
// content: "Loading..."
// });
//present the loadingscreen
// loading.present();
//reset the noEvents boolean.
this.noEvents = true;
//call the api and get all events
this.apiCaller.getEvents()
.subscribe(response => {
console.log("RESP:"+response);
//response is list of events
this.events = response;
//if the event is not empty, set noEvents to false.
if(this.events.length > 0){ //<----------------------------FAILS HERE
this.noEvents = false;
}
//close the loading message.
// loading.dismiss();
});
}
}
EventPage -- Spec
import { TestBed, inject, tick, fakeAsync } from '@angular/core/testing';
import { BaseRequestOptions, Http, ConnectionBackend, Response, ResponseOptions} from '@angular/http';
import { FormsModule } from '@angular/forms';
import { NavController, LoadingController } from 'ionic-angular';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { mockNavController, mockApp } from 'ionic-angular/util/mock-providers';
import { EventsPage } from './events.component';
import { MockAPICaller } from '../../services/mocks/apicaller.service';
import { APICaller } from '../../services/apicaller.service';
describe('Component: EventsComponent', () => {
let mockAPICaller : MockAPICaller = new MockAPICaller();
let loadingCtrl : LoadingController = new LoadingController(this);
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [EventsPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{provide: APICaller, useValue: mockAPICaller},
{provide: NavController, useValue: mockNavController },
{provide: LoadingController, useValue: loadingCtrl},
],
imports: [FormsModule]
});
TestBed.overrideComponent(EventsPage,{
set: {
providers: [
{provide: APICaller, useValue: mockAPICaller}
]
}
});
});
it('should return all events', () => {
let fixture = TestBed.createComponent(EventsPage);
let eventsPage = fixture.debugElement.componentInstance;
fixture.detectChanges();
mockAPICaller.setResponse(JSON.stringify(`[{
id: 4,
title: 'Weekend',
eventdate: '24/09/2016',
kind: 'closed',
startingtime: '18:00',
endtime: '21:00',
description: 'Go Home'
}]`));
eventsPage.getEvents();
fixture.detectChanges();
console.log(eventsPage.events);
});
});
MockAPICaller
import { SpyObject } from './helper';
import { APICaller } from '../apicaller.service';
import Spy = jasmine.Spy;
export class MockAPICaller extends SpyObject {
getEventsSpy: Spy;
searchEventSpy:Spy;
getParticipantSpy:Spy;
getEventParticipantsSpy:Spy;
searchEventParticipantSpy:Spy;
addNewCommentSpy:Spy;
updateCommentSpy:Spy;
deleteCommentSpy:Spy;
getUsernameSpy:Spy;
presentSuccessMessageSpy:Spy;
fakeResponse:any;
constructor(){
super( APICaller );
this.fakeResponse = null;
this.getEventsSpy = this.spy('getEvents').andReturn(this);
this.searchEventSpy = this.spy('searchEvent').andReturn(this);
this.getParticipantSpy = this.spy('getParticipant').andReturn(this);
this.getEventParticipantsSpy = this.spy('getEventParticipant').andReturn(this);
this.searchEventParticipantSpy = this.spy('searchEventParticipant').andReturn(this);
this.addNewCommentSpy = this.spy('addNewComment').andReturn(this);
this.updateCommentSpy = this.spy('updateComment').andReturn(this);
this.deleteCommentSpy = this.spy('deleteComment').andReturn(this);
this.getUsernameSpy = this.spy('getUsername').andReturn(this);
this.presentSuccessMessageSpy = this.spy('presentSuccessMessage').andReturn(this);
}
subscribe(callback: any){
callback(this.fakeResponse);
}
setResponse(json:any):void{
this.fakeResponse = json;
}
}