Erste Entschuldigung für mein Englisch.Angular, Test, Dependency Injection, http.get ... Hilfe zu verstehen
Ich benutze Angular und entwickle einen einfachen Service mit seinem Test.
Der Dienst lädt eine JSON-Datei mit der http.get-Methode und speichert den Inhalt in einer Variablen. Das Ziel ist nicht wichtig.
Unter einem Code, der funktioniert:
Zuerst wird der Service
import {Http} from '@angular/http';
import {Injectable} from '@angular/core';
import {Constants} from 'config/constants';
import 'rxjs/Rx';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class LoadJsonFileService {
private config: Object = null;
constructor(private http: Http) {
}
private loadJsonAndUpdateConfig() {
this.http
.get(Constants.CONFIG_FILE_NAME)
.map(response => response.json())
.catch((error: any): any => {
return Observable.throw(error.json().error || 'Server error');
}).subscribe((configJson) => {
this.config = configJson;
});
}
public getConfig(key: string): string {
if (!this.config) {
this.loadJsonAndUpdateConfig();
}
return this.config[key];
}
}
Dann der Test:
import {BaseRequestOptions, ConnectionBackend, Http, RequestOptions, Response, ResponseOptions} from '@angular/http';
import {MockBackend, MockConnection} from '@angular/http/testing';
import {LoadJsonFileService} from './load-json-file.service';
import {inject, TestBed} from '@angular/core/testing';
describe('Test suite ...',() => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: RequestOptions, useClass: BaseRequestOptions},
{provide: ConnectionBackend, useClass: MockBackend},
Http,
LoadJsonFileService
]
});
});
it('The test ...', inject([ConnectionBackend, LoadJsonFileService],
(backend,
service: LoadJsonFileService) => {
backend.connections.subscribe((c: MockConnection) => {
c.mockRespond(new Response(new ResponseOptions({body: {key: 'foo'}})));
});
expect(service.getConfig('key')).toBe('foo');
}));
});
-Test ist OK.
Der Code, die nicht funktionieren, und ich weiß nicht, warum:
import {Http} from '@angular/http';
import {Injectable} from '@angular/core';
import {Constants} from 'config/constants';
import 'rxjs/Rx';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class LoadJsonFileService {
private config: Object = null;
constructor(private http: Http) {
this.loadJsonAndUpdateConfig();
}
private loadJsonAndUpdateConfig() {
this.http
.get(Constants.CONFIG_FILE_NAME)
.map(response => response.json())
.catch((error: any): any => {
return Observable.throw(error.json().error || 'Server error');
}).subscribe((configJson) => {
this.config = configJson;
});
}
public getConfig(key: string): string {
return this.config[key];
}
}
Der Unterschied den Aufruf von this.loadJsonAndUpdateConfig() im Konstruktor und nicht in der getConfig Methode. Test nicht bestanden:
TypeError: null is not an object (evaluating 'this.config[key]')
Als ich setzen einige der Methode subscribe debuggen nie dergleichen auslösen, wenn http.get wird rufen nie ...
Ich bin verwirrt ist mir jemand dieses Verhalten erklären kann?
Danke,
Stef
Dank aber die Frage war nicht, warum die Null-Fehler (dies ist eine Folge), mein Code hinzufügen, nur zu Stellen Sie sich die Frage vor: Warum wird die Methode 'http.get' nicht aufgerufen, wenn die Methode' loadJsonAndUpdateConfig() 'im Konstruktor aufgerufen wird, aber aufgerufen wird, wenn ich sie in die Methode' getConfig' setze? – Wilda