2016-09-30 3 views
5

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.

+0

Ich bin auch mit diesem Problem konfrontiert. Haben Sie dafür eine Lösung gefunden? @ryzhak –

+0

Ich bin auch auf der Suche nach einer Antwort auf diese –

+0

Das gleiche Problem hier ..:/ Hat jemand vielleicht eine Lösung gefunden? – kriskodzi

Antwort

2

Ok Jungs, nach einigen Schwierigkeiten habe ich gefunden, dass beobachtbare für forkJoin abgeschlossen werden muss, um es zu fangen.
Also, wenn Sie
project.next(something)
anrufen, ist es nicht genug.
Sie müssen auch anrufen:
project.complete()
, damit es funktioniert!

Verwandte Themen