Angular 2 - Mocking - 响应为空 [英] Angular 2 - Mocking - response is null
问题描述
Angular 2.0.0 - Ionic 2 RC0 - Npm 3.10.8 - Node v4.5.0 - Karma 1.3.0 - Jasmine 2.5.2
上一个问题: Angular 2 - Mocking - 没有HTTP提供商
我现在在执行时遇到新错误 npm test
: null不是对象(评估'_this.events.length')
I'm now getting a new error while executing npm test
: null is not an object (evaluating '_this.events.length')
这是由以下代码触发的: if(this.events.length> 0){
在EventsPage中,这意味着我在 events.spec.ts
以某种方式没有正确返回。
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.
我是嘲笑Angular2的新手,所以它很可能是一个菜鸟错误。
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;
}
}
推荐答案
你应该在创建组件之前在模拟上设置响应。您在组件构造函数中调用 getEvents
,并且模拟尚未设置数据。
You should set the response on the mock before creating the component. You are calling getEvents
in the component constructor, and the mock hasn't set the data yet.
it('should return all events', () => {
mockAPICaller.setResponse(JSON.stringify(`[{
id: 4,
title: 'Weekend',
eventdate: '24/09/2016',
kind: 'closed',
startingtime: '18:00',
endtime: '21:00',
description: 'Go Home'
}]`));
let fixture = TestBed.createComponent(EventsPage);
let eventsPage = fixture.debugElement.componentInstance;
fixture.detectChanges();
eventsPage.getEvents();
fixture.detectChanges();
console.log(eventsPage.events);
});
这篇关于Angular 2 - Mocking - 响应为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!