2016-04-17 12 views
8

Mam składnik ofertę z następującego kodu:Angular2 - Testowanie ngOninit w komponentach

///<reference path="../../node_modules/angular2/typings/browser.d.ts"/> 
import { Component, OnInit } from 'angular2/core'; 
import { ROUTER_DIRECTIVES } from 'angular2/router'; 

import { Employee } from '../models/employee'; 
import { EmployeeListServiceComponent } from '../services/employee-list-service.component'; 

@Component({ 
    selector: 'employee-list', 
    template: ` 
    <ul class="employees"> 
    <li *ngFor="#employee of employees"> 
    <a [routerLink]="['EmployeeDetail', {id: employee.id}]"> 
     <span class="badge">{{employee.id}}</span> 
     {{employee.name}} 
    </a> 
    </li> 
</ul> 
    `, 
    directives: [ROUTER_DIRECTIVES], 
    providers: [EmployeeListServiceComponent] 
}) 

export class EmployeeListComponent implements OnInit { 
    public employees: Employee[]; 
    public errorMessage: string; 

    constructor(
    private _listingService: EmployeeListServiceComponent 
){} 

    ngOnInit() { 
    this._listingService.getEmployees().subscribe(
        employees => this.employees = employees, 
        error => this.errorMessage = <any>error 
        ); 
    } 
} 

pragnę pisać testy jednostkowe dla haka ngOninit. Napisałem następujący test:

/// <reference path="../../typings/main/ambient/jasmine/jasmine.d.ts" /> 

import { 
    it, 
    describe, 
    expect, 
    TestComponentBuilder, 
    injectAsync, 
    setBaseTestProviders, 
    beforeEachProviders, 
} from "angular2/testing"; 
import { Component, provide, ApplicationRef, OnInit } from "angular2/core"; 
import { 
    TEST_BROWSER_PLATFORM_PROVIDERS, 
    TEST_BROWSER_APPLICATION_PROVIDERS 
} from "angular2/platform/testing/browser"; 
import { 
    ROUTER_DIRECTIVES, 
    ROUTER_PROVIDERS, 
    ROUTER_PRIMARY_COMPONENT, 
    APP_BASE_HREF 
} from 'angular2/router'; 
import {XHRBackend, HTTP_PROVIDERS} from "angular2/http"; 
import { MockApplicationRef } from 'angular2/src/mock/mock_application_ref'; 
import {MockBackend } from "angular2/src/http/backends/mock_backend"; 
import {Observable} from 'rxjs/Rx'; 
import 'rxjs/Rx'; 

import { Employee } from '../models/employee'; 
import { EmployeeListComponent } from './list.component'; 
import { EmployeeListServiceComponent } from '../services/employee-list-service.component'; 


class MockEmployeeListServiceComponent { 

    getEmployees() { 
     return Observable.of([ 
      { 
       "id": 1, 
       "name": "Abhinav Mishra" 
      } 
     ]); 
    } 
} 


@Component({ 
    template: '<employee-list></employee-list>', 
    directives: [EmployeeListComponent], 
    providers: [MockEmployeeListServiceComponent] 
}) 
class TestMyList {} 


describe('Employee List Tests',() => { 
    setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS); 

    beforeEachProviders(() => { 
     return [ 
      ROUTER_DIRECTIVES, 
      ROUTER_PROVIDERS, 
      HTTP_PROVIDERS, 
      provide(EmployeeListServiceComponent, {useClass: MockEmployeeListServiceComponent}), 
      provide(XHRBackend, {useClass: MockBackend}), 
      provide(APP_BASE_HREF, {useValue: '/'}), 
      provide(ROUTER_PRIMARY_COMPONENT, {useValue: EmployeeListComponent}), 
      provide(ApplicationRef, {useClass: MockApplicationRef}) 
     ] 
    }); 

    it('Should be true', 
     injectAsync([TestComponentBuilder], (tcb) => { 
      return tcb 
       .createAsync(TestMyList) 
       .then((fixture) => { 
        fixture.detectChanges(); 
        var compiled = fixture.debugElement.nativeElement; 
        console.log(compiled.innerHTML); 
        expect(true).toBe(true); 
       }); 
     }) 
    ); 
}); 

Jednak wyjście console.log w teście jest pusty ul tag następująco:

'<employee-list> 
    <ul class="employees"> 
    <!--template bindings={}--> 
</ul> 
    </employee-list>' 

Czy ktoś może zaproponować mi właściwą drogę testów jednostkowych pisanie dla komponentu haki?

ROZWIĄZANIE

Mock żądanie HTTP w bloku injectAsync następująco:

backend.connections.subscribe(
       (connection:MockConnection) => { 
        var options = new ResponseOptions({ 
         body: [ 
          { 
           "id": 1, 
           "name": "Abhinav Mishra" 
          } 
         ] 
        }); 

        var response = new Response(options); 

        connection.mockRespond(response); 
       } 
      ); 

Jednak teraz otrzymuję inny błąd w następujący sposób:

Failed: EXCEPTION: Component "EmployeeListComponent" has no route config. in [['EmployeeDetail', {id: employee.id}] in [email protected]:7] 
     ORIGINAL EXCEPTION: Component "EmployeeListComponent" has no route config. 
     ORIGINAL STACKTRACE: 
     Error: Component "EmployeeListComponent" has no route config. 

Odpowiedz

3

Jeśli zadzwonisz asynchronicznie kod w ngOnInit() nie można założyć, że jest on zakończony po wykonaniu console.log(...) ed. this.employees jest ustawiany tylko wtedy, gdy wywołanie zwrotne przekazane do użytkownika subscribe(...) zostanie wywołane po otrzymaniu odpowiedzi.

Jeśli używasz MockBackend można kontrolować odpowiedź i po odpowiedź została przekazana trzeba uruchomić fixture.detectChanges() ponownie, aby składnik ponownego renderowania ze zaktualizowanymi danymi, a następnie można przeczytać innerHTML i oczekiwać, że zawierają renderowany treści .

+0

Twoje rozwiązanie zadziałało. Ale teraz dostaję następujący błąd. Czy możesz zaproponować jakieś obejście? 'Błąd: WYJĄTEK: Komponent" EmployeeListComponent "nie ma konfiguracji trasy. w [["EmployeeDetail", {id: employee.id}] w EmployeeListComponent @ 3: 7] ORYGINALNY WYJĄTEK: Komponent "EmployeeListComponent" nie ma konfiguracji trasy. " – abhinavmsra

+0

Może http://stackoverflow.com/questions/35011972/ Składnik-undefined-ma-no-route-config-aka-how-to-configure-angle-2-router-fo? rq = 1 –

+0

ciągle otrzymuje ten sam błąd. czy możesz tutaj dodać przykładowy kod? – abhinavmsra

Powiązane problemy