Ich habe eine LogComponent in meiner Anwendung. Inside ngOnInit Ich abrufen Protokolle von einem Server über LogService und zeigen sie in einem Raster.eckig 2 Test eine Komponente mit forkJoin
Hier gibt es 2 Möglichkeiten, wie es zu tun:
Die erste:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Log } from './log';
import { LogService } from './log.service';
import * as globals from '../../globals';
import { DataTransformService, HttpHandlerService, StateManagerService } from '../../shared';
@Component({
selector: 'app-log',
templateUrl: 'log.component.html',
styleUrls: ['log.component.css'],
providers: [ DataTransformService, HttpHandlerService, LogService, StateManagerService]
})
export class LogComponent implements OnInit {
localGlobals: any = globals;
logs: Log[];
currentPage: number;
totalRecords: number = 0;
firstRowIndex: number = 0;
constructor(
private stateManagerService: StateManagerService,
private httpHandlerService: HttpHandlerService,
private logService: LogService,
private dataTransformService: DataTransformService,
private router: Router
) {}
ngOnInit() {
//get page number from local storage
this.currentPage = this.stateManagerService.getParamFromState(this.router.url, 'page');
this.firstRowIndex = this.currentPage * this.localGlobals.ROWS_PER_PAGE - this.localGlobals.ROWS_PER_PAGE;
//get total count
let respHandler = (res: any) => {
this.totalRecords = res.headers.get('X-Pagination-Total-Count');
return this.httpHandlerService.extractData(res);
};
this.logService.search(this.currentPage, respHandler).subscribe(
logs => {
this.logs = logs;
},
err => console.error(err)
);
}
}
Der erste Ansatz nutzt diese Funktion Protokolle abzurufen:
this.logService.search(this.currentPage, respHandler).subscribe(
logs => {
this.logs = logs;
},
err => console.error(err)
);
Der zweite Weg zum Abrufen Protokolle sind über Observable.forkJoin:
Der zweite Ansatz verwendet diese Funktion Protokolle abzurufen:
Observable.forkJoin(
this.logService.search(this.currentPage, respHandler)
).subscribe(
data => {
this.logs = data[0];
},
err => console.error(err)
);
ich einen Test für diese Komponente haben, die überprüft, ob Eigenschaften nach der init initialisiert werden:
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { ReplaySubject } from 'rxjs/Rx';
import { Log } from './log';
import { LogComponent } from './log.component';
import { LogService } from './log.service';
import { DataTransformService, HttpHandlerService, LocalStorageService, StateManagerService } from '../../shared';
let comp: LogComponent;
let fixture: ComponentFixture<LogComponent>;
let de: DebugElement;
describe('LogComponent',() => {
// async compile html and css
beforeEach(async(() => {
let project = new ReplaySubject(1);
let logServiceStub = {
search: (pageNum: number, respHandler: any) => {
let logs = [
{ id: 1, ip: '127.0.0.1', user_id: 1, notification_event_id: 1, created_at: 1 },
{ id: 2, ip: '127.0.0.2', user_id: 2, notification_event_id: 2, created_at: 2 }
];
project.next(logs);
return project;
}
};
let routerStub = {
url: 'log_url'
};
TestBed.configureTestingModule({
declarations: [ LogComponent ],
imports: [ FormsModule ],
providers: [
DataTransformService,
HttpHandlerService,
LocalStorageService,
{ provide: Router, useValue: routerStub },
StateManagerService
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.overrideComponent(LogComponent, {
set: {
providers: [
{ provide: LogService, useValue: logServiceStub }
]
}
})
.compileComponents();
}));
// synchronous
beforeEach(() => {
fixture = TestBed.createComponent(LogComponent);
// LogComponent test instance
comp = fixture.componentInstance;
de = fixture.debugElement;
});
it('initial variables are set after init',() => {
fixture.detectChanges();
console.log(comp.logs);
//TODO: test not working when requests are in forkJoin
expect(comp.currentPage).toBe(1);
expect(comp.firstRowIndex).toBe(0);
expect(comp.logs).not.toBeUndefined();
expect(comp.logs.length).toBe(2);
});
});
Problem: wenn ich Testlauf mit dem 1. Ansatz (ohne Observable.forkJoin) funktioniert es gut. ABER wenn ich Test mit dem zweiten Ansatz laufen (mit Observable.forkJoin) es nicht mit dem Fehler:
Expected undefined not to be undefined.
So Protokolle werden nach fixture.detectChanges nicht initialisiert(). Es scheint, als ob eine Anfrage innerhalb der Observable.forkJoin() ist, dann wird die Initialisierung nicht ausgeführt. Ich verstehe, dass es nur 1 Anfrage in Observable.forkJoin() gibt und ich kann mit dem ersten Ansatz gehen, aber ich habe andere Komponenten im System, die mehr als 1 Anfrage verwendet, so dass ich dieses Problem gelöst werden muss.
Hoffe, du hast was ich meine.
Vielen Dank im Voraus.
Ich bin auch mit diesem Problem konfrontiert. Haben Sie dafür eine Lösung gefunden? @ryzhak –
Ich bin auch auf der Suche nach einer Antwort auf diese –
Das gleiche Problem hier ..:/ Hat jemand vielleicht eine Lösung gefunden? – kriskodzi