12

hat Da Angular-Team in Angular 2 RC-Versionen ständig upgrade/deprecated, stieß ich auf dieses Problem.Angular 2 RC4: Komponententestkomponente, die Abhängigkeitsinjektion hat einen Dienst, der seine eigene

Ich habe eine Komponente, die eine Dependency Injection (DI) hat, die eigentlich ein Dienst ist (UserService in diesem Fall). Dieser UserService hat natürlich einige eigene DIs. Nach dem Update auf die neueste RC4 von Angular 2 habe ich festgestellt, dass ich keine ähnlichen Tests mehr erstellen kann.

So wie die Dokumente nicht etwas relatives hier erwähnen, ist mein Code (vereinfacht für diese Frage).

Meine Komponente:

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(); 
    } 

} 

Komponente DI, Userservice whic wie Sie einige DIs (Router, AuthHttp & Http) sehen kann, hat:

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() 
    ); 
    } 

} 

Und hier ist der Test für die Komponente:

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(); 
    })); 

}); 

Mach dir keine Sorgen über das (es) für jetzt.

Wie Sie sehen können, ich, m die entsprechenden Anbieter auf der beforeEachProviders hinzufügen.

In diesem Fall erhalte ich einen Fehler, wenn ich die Tests ausführen:

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

Welche der erwartet wird, sagen wir mal.

Um also nicht, diese Fehler bekomme ich hinzufüge, die DIs Dienst in den Anbietern auch:

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

Aber jetzt bin ich, immer diese Fehlermeldung:

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.

Ich versuche wirklich herauszufinden, was passiert, also habe ich hier einige Antworten gefunden, aber ALLE sind veraltet und decken die alten router-deprecated oder angular2/router ab, aber beide sind veraltet und decken diesen Fall nicht ab.

Ich würde gerne etwas Hilfe zu diesem und vielleicht einige Ressourcen wie ich kann nichts in Bezug auf die neueste Version von Router finden: und RC4.

Dank

UPDATE!

Ich schaffe es, die beiden oben genannten Fehler zu umgehen und jetzt kann ich auf die Komponente zugreifen. Hier ist die Beschreibung Code:

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(); 
    }); 

}); 

Aber es scheint, dass auch, dass der DI-Dienst injiziert und zugänglich die DIs des Dienstes nicht. So, jetzt bekomme ich diesen Fehler:

TypeError: this.authHttp.get is not a function

Irgendwelche Ideen?

+0

Ich habe ähnliche Probleme mit einem Service bekommen das verwendet http aus einem Jasmin-Test. Leider habe ich bei der Art der Tests mit der neuesten RC keine Dokumentation gefunden. – jsight

+0

Haben Sie versucht, eine Kopie für UserService und Router zu verwenden? – tymspy

+0

@tymspy Sorry wegen vieler Dinge zu tun, noch nicht. Aber danke, wenn ich es versuche, werde ich Sie über die Ergebnisse informieren. –

Antwort

3

Es sieht so aus, als ob Sie ein Abhängigkeitsschleifen-Problem hatten, da Ihr UserSerivce auch AuthHttp, Http, etc injizieren muss ... es wird wirklich einmal gestört, wenn Sie Ihre Komponente testen müssen. Mein Weg ist erstellen nur ein Mock UserSerivce und senden Sie das erwarten verspottet Wert durch UserService.logout() Methode, da Sie müssen in Userservice nicht wissen, was wirklich passiert ist, alles, was Sie brauchen, ist nur ein Rückgabewert:

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

Dann , in Testsuite:

import { provide } from '@angular/core' 

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

... detail test code here 

Ich hoffe, das funktioniert für Sie. Und hier ist ein Beitrag, der mir sehr hilft:

0

Mit RC4 sind einige Problemumgehungen erforderlich, http in einem Test zu verwenden. Siehe auch diese Frage (soll in RC5 festgelegt werden):

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

Addiert man diese zu meinem Einheit-tests.html regelt es für mich:

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