2016-07-15 156 views
12

Poiché il team Angular esegue costantemente l'upgrade/deprecazione di roba nelle versioni di Angular 2 RC, ho riscontrato questo problema.Angolare 2 RC4: componente di test unità che ha un'iniezione dipendente un servizio che ha il proprio

Ho un componente che ha una dipendenza (DI), che in realtà è un servizio (UserService in questo caso). Questo UserService ha ovviamente alcuni DI propri. Dopo l'aggiornamento all'ultima RC4 di Angular 2 mi sono reso conto che non posso più creare test simili.

Così come i documenti non menzionano qualcosa di relativo, ecco il mio codice (semplificato per questa domanda).

La mia componente:

import { Component } from '@angular/core'; 
import { MdButton } from '@angular2-material/button'; 
import { 
    MdIcon, 
    MdIconRegistry 
} from '@angular2-material/icon'; 
import { UserService } from '../../services/index'; 

@Component({ 
    moduleId: module.id, 
    selector: 'logout-button', 
    templateUrl: 'logout-button.component.html', 
    styleUrls: ['logout-button.component.css'], 
    providers: [MdIconRegistry, UserService], 
    directives: [MdButton, MdIcon] 
}) 
export class LogoutButtonComponent { 

    constructor(public userService: UserService) {} 

    /** 
    * Call UserService and logout() method 
    */ 
    logout() { 
    this.userService.logout(); 
    } 

} 

del componente DI, UserService whic come si può vedere ha una certa dis (Router, AuthHttp & Http):

import { Injectable } from '@angular/core'; 
import { 
    Http, 
    Headers 
} from '@angular/http'; 
import { 
    AuthHttp, 
    JwtHelper 
} from 'angular2-jwt'; 
import { Router } from '@angular/router'; 
import { UMS } from '../common/index'; 

@Injectable() 
export class UserService { 

    constructor(
    private router: Router, 
    private authHttp: AuthHttp, 
    private http: Http) { 

     this.router = router; 
     this.authHttp = authHttp; 
     this.http = http; 
    } 

    /** 
    * Logs out user 
    */ 
    public logout() { 
     this.authHttp.get(UMS.url + UMS.apis.logout) 
     .subscribe(
     data => this.logoutSuccess(), 
     err => this.logoutSuccess() 
    ); 
    } 

} 

Ed ecco il test per il componente:

import { By }   from '@angular/platform-browser'; 
import { DebugElement } from '@angular/core'; 

import { 
    beforeEach, 
    beforeEachProviders, 
    describe, 
    expect, 
    it, 
    inject, 
    fakeAsync, 
    TestComponentBuilder 
} from '@angular/core/testing'; 

import { AuthHttp } from 'angular2-jwt'; 
import { Router } from '@angular/router'; 
import { Http } from '@angular/http'; 
import { LogoutButtonComponent } from './logout-button.component'; 
import { UserService } from '../../services/index'; 

describe('Component: LogoutButtonComponent',() => { 



    beforeEachProviders(() => [ 
    LogoutButtonComponent, 
    UserService 
    ]); 

    it('should inject UserService', inject([LogoutButtonComponent], 
    (component: LogoutButtonComponent) => { 
     expect(component).toBeTruthy(); 
    })); 

}); 

Non preoccuparti per il (esso) per ora.

Come si può vedere I; m aggiungendo i relativi provider sullo beforeEachProviders.

In questo caso sto ottenendo un errore quando ho eseguito i test:

Error: No provider for Router! (LogoutButtonComponent -> UserService -> Router)

che si prevede diciamo.

Quindi, al fine di non avere quegli errori che sto aggiungendo DIs del servizio nei provider anche:

beforeEachProviders(() => [ 
    LogoutButtonComponent, 
    Router, 
    AuthHttp, 
    Http, 
    UserService 
    ]); 

ma ora sto, questo errore:

Error: Cannot resolve all parameters for 'Router'(?, ?, ?, ?, ?, ?, ?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'Router' is decorated with Injectable.

Sto davvero cercando di capire cosa sta succedendo, quindi ho trovato alcune risposte correlate qui ma TUTTE sono obsolete e copre il vecchio router-deprecated o angular2/router ma entrambi sono deprecati e non coprono questo caso.

Mi piacerebbe un po 'di aiuto su questo e forse alcune risorse in quanto non riesco a trovare nulla relativo alla versione più recente di Router: "@angular/router": "3.0.0-beta.2" e RC4.

Grazie

AGGIORNAMENTO!

Sono riuscito a ignorare i due errori sopra e ora posso accedere al componente. Ecco il codice descrizione:

describe('Component: LogoutButtonComponent',() => { 

    let component: LogoutButtonComponent; 
    let router: any = Router; 
    let authHttp: any = AuthHttp; 
    let http: any = Http; 
    let service: any = new UserService(router, authHttp, http); 

    beforeEachProviders(() => [ 
    LogoutButtonComponent 
    ]); 

    beforeEach(() => { 
    component = new LogoutButtonComponent(service); 
    }); 

    it('should inject UserService',() => { 
    expect(component.userService).toBeTruthy(); 
    }); 

    it('should logout user',() => { 
    localStorage.setItem('token', 'FOO'); 
    component.logout(); 
    expect(localStorage.getItem('token')).toBeUndefined(); 
    }); 

}); 

Ma sembra che anche che il servizio DI viene iniettato ed accessibile del DIS del servizio non sono. Quindi ora ho questo errore:

TypeError: this.authHttp.get is not a function

Qualche idea?

+0

sto avendo problemi simili con ottenere un servizio che usa http da un test di gelsomino. Sfortunatamente, non ho trovato molto sulla documentazione di questi tipi di test con l'ultimo RC. – jsight

+0

Hai provato a usare una simulazione per UserService e Router? – tymspy

+0

@tymspy Ci scusiamo per un sacco di cose da fare, non ancora. ma grazie, quando ci proverò, ti informerò sui risultati. –

risposta

3

Sembra che tu stia vivendo un problema di loop delle dipendenze, perché anche il tuo UserSerivce deve iniettare AuthHttp, Http, ecc ... sarà davvero disturbato una volta se hai bisogno di testare il tuo componente. Il mio modo è solo creare un UserSerivce finta e restituire il valore deriso aspettare attraverso UserService.logout() metodo, perché non c'è bisogno di sapere cosa sia realmente accaduto in UserService, tutto ciò che serve è solo un valore di ritorno:

let MockUserService = { 
    logout() { 
    // return some value you need 
    } 
} 

Poi , in test suite:

import { provide } from '@angular/core' 

beforeEachProviders(() => [ 
    provide(UserService, {useClass: MockUserService}) 
]) 

... detail test code here 

Spero che questo funzioni per voi. Ed ecco un post che mi aiuta molto: https://developers.livechatinc.com/blog/testing-angular-2-apps-dependency-injection-and-components/

0

Con RC4, alcune soluzioni sono necessari per utilizzare http in un test. Vedi anche questo problema (dovrebbe essere fissata in RC5):

https://github.com/angular/angular/issues/9294

L'aggiunta di questo alla mia unità-tests.html fisso per me:

System.import('@angular/platform-browser/src/browser/browser_adapter').then(function(browser_adapter) { 
    browser_adapter.BrowserDomAdapter.makeCurrent(); 
}) 
Problemi correlati