2016-04-12 7 views
2

Ich habe eine einfache, aber komplizierte (vorerst) Komponente: Es ist nur ein Login-Formular , also werde ich nicht den HTML-Code einfügen. Sieht wie folgt aus:Angular2: Testen Komponente mit Abhängigkeits-Injektion

login.component.ts 

@Component({ 
    selector: 'login', 
    providers: [ModuleLoaderService, LoginService], 
    templateUrl: 'login.component.html', 
    directives: [CORE_DIRECTIVES, RouterLink], 
    pipes: [TranslationPipe] 
}) 

export class LoginComponent { 

//... some stuff 
    constructor(public router: Router, public http: Http, private _translation: TranslationService, 
       private _loginService: LoginService, private _moduleLoaderService: ModuleLoaderService) { 
        // do stuff using translation, etc 
       } 

       .... 
ngOnInit() { 
`....bla bla 
} 

Hier ist der Test, den ich versuche zu starten, was ich denke, ist völlig aus:

describe('Login form',() => { 
    beforeEachProviders(() => [ 
           provide(Http, {useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => { 
            return new Http(backend, defaultOptions); 
           }, deps: [MockBackend, BaseRequestOptions]}), 
           TranslationService, 
           LoginService 
    ]); 

    it('should check translated labels', injectAsync([TestComponentBuilder], (tcb) => { 
     return tcb.createAsync(MockLoginComponent).then((fixture) => { 
      fixture.detectChanges(); 
      let compiled = fixture.debugElement.nativeElement; 
      expect(true).toBe(true); 
     }); 
    })); 
}); 

und meine translation:

import { Injectable } from 'angular2/core'; 
import { TranslateService } from 'ng2-translate'; 

@Injectable() 
export class TranslationService { 

    constructor(private _translate: TranslateService) { 
     // 
    } 

Fehler:

fehlgeschlagen Ressource laden: Der Server antwortet mit dem Status 404 (Not Found): http://localhost:9876/ng2-translate

Ich möchte beginnen, Tests für diese Komponente zu schreiben. Der erste Test, den ich dachte, wäre ein guter Anfang: Testen der übersetzten Etiketten ist korrekt (oder alles andere einfach genug). Ich habe keine Ahnung, wie man all diese Konstruktorargumente injizieren oder verspotten kann. Jeder Hinweis wirklich geschätzt.

Update: Also irgendwie ich Abhängigkeits jetzt ignoriert, und ich war in der Lage, tatsächlich die Komponente für den Test zu erhalten:

describe('Login form',() => { 
    beforeEachProviders(() => [ 
     HTTP_PROVIDERS, 
     provide(XHRBackend, { useClass: MockBackend }), 
     provide(Router, { useClass: MockRouter }), 
     TranslateService, 
     TranslationService, 
     LoginService, 
     provide(TranslateLoader, { 
      useFactory: (http: Http) => new TranslateStaticLoader(http, 'assets/i18n', '.json'), 
      deps: [Http] 
     }), 
     TranslateService, 
     ModuleLoaderService 
    ]); 

    it('should pre-populate username and pass from localStorage', injectAsync([TestComponentBuilder], (tcb) => { 
     return tcb.createAsync(LoginComponent).then((fixture) => { 
      fixture.detectChanges(); 
      let compiled = fixture.debugElement.nativeElement; 
      localStorage.setItem('username', 'storedUsername');   
      expect(compiled.querySelector('input .ng-untouched')).toHaveText('storedUsername'); 
     }); 
    })); 

Der CSS-Selektor scheint nicht zu funktionieren und die übersetzten Etiketten nicht zeigen in Karma Browser entweder ...

+0

Was ist ein konkretes Beispiel über das, was Sie testen möchten. Was hast du probiert? Wo ist das Problem? –

+0

Vielen Dank für Ihre Suche. Also fügte ich meinen Versuch der Beschreibung hinzu: Wie ich bereits erwähnt habe, muss ich mit dem Testen dieser Komponente beginnen, denn jetzt muss ich nur noch testen, ob die übersetzten Etiketten für dieses Login-Formular vorhanden und korrekt sind. Dazu dachte ich mir, ich müsste den TranslationService einspielen (siehe meinen Übersetzungsdienst, der auf ng2-translate basiert). Offensichtlich funktioniert es nicht, weil ich keine Ahnung habe, wie das geht. Vielen Dank ! –

+1

Ich bin einen Schritt weiter: Ich habe den Fehler behoben, einige der benötigten Bibliotheken nicht zu haben, indem ich sie zu der karma.conf.js hinzufügte. Jetzt kann ich mich mit dem eigentlichen Test befassen. Nächstes: repariere die Anbieter! –

Antwort

0

Dies könnte helfen. Ich benutze TS nicht selbst (nur Dart) aber es führt die Tests ohne Fehler durch (testet eigentlich gar nichts).

Einige Links, die

Test hilfreich sein könnte/some.spec.ts

import {setBaseTestProviders} from 'angular2/testing'; 
import { 
    TEST_BROWSER_PLATFORM_PROVIDERS, 
    TEST_BROWSER_APPLICATION_PROVIDERS 
} from 'angular2/platform/testing/browser'; 
import {Http, ConnectionBackend, BaseRequestOptions} from 'angular2/http'; 
import {ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router'; 
import { 
    //AsyncTestCompleter, 
    TestComponentBuilder, 
    beforeEachProviders, 
    beforeEach, 
    describe, 
    // el, 
    expect, 
    inject, 
    injectAsync, 
    it, 
} from 'angular2/testing'; 
import {Component, provide, ElementRef} from 'angular2/core'; 
import {LoginComponent, TranslationService} from '../src/app'; 
import {MockBackend} from "angular2/src/http/backends/mock_backend"; 

setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, 
    TEST_BROWSER_APPLICATION_PROVIDERS); 

describe('Login form',() => { 
    beforeEachProviders(() => [provide(ROUTER_PRIMARY_COMPONENT, {useClass: LoginComponent}), TestComponentBuilder, ROUTER_PROVIDERS, 
    provide(Http, { 
     useFactory: (backend:ConnectionBackend, defaultOptions:BaseRequestOptions) => { 
     return new Http(backend, defaultOptions); 
     }, deps: [MockBackend, BaseRequestOptions] 
    }), 
    TranslationService, 
    ]); 

    it('should check translated labels', injectAsync([TestComponentBuilder], (tcb) => { 
    return tcb.createAsync(LoginComponent).then((fixture) => { 
     fixture.detectChanges(); 
     let compiled = fixture.debugElement.nativeElement; 
     console.debug(compiled); 
     expect(true).toBe(true); 
    }); 
    })); 
}); 

test.html

<!DOCTYPE html> 
<html> 

<head> 
    <title>angular2 playground</title> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script> 


    <link rel="stylesheet" href="style.css"/> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/angular2-polyfills.js"></script> 
    <script src="https://code.angularjs.org/tools/system.js"></script> 
    <script src="https://code.angularjs.org/tools/typescript.js"></script> 
    <script src="config.js"></script> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/Rx.js"></script> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js"></script> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/router.dev.js"></script> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/http.dev.js"></script> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/testing.dev.js"></script> 
    <script> 

     Promise.all([ 
      System.import('test/some.spec.ts') 
     ]) 
     .then(window.onload) 
       .catch(console.error.bind(console)); 
    </script> 
</head> 
<body> 
</body> 
</html> 

src/app.ts

import {EventEmitter, HostListener, Component, Directive, Output} from 'angular2/core'; 
import {Http} from 'angular2/http'; 
import {RouterLink, Router, RouteConfig, RouterOutlet} from 'angular2/router'; 


export class TranslationService { 
} 

@Component({ 
    selector: 'home-cmp', 
    template: '<div>home</div>' 
}) 
class HomeComponent { 
} 

@Component({ 
    selector: 'login', 
    providers: [TranslationService], 
    template: '<div>login</div>', 
}) 
export class LoginComponent { 
    constructor(private _translation:TranslationService) { 
    // do stuff using translation, etc 
    } 
} 

@Component({ 
    directives: [RouterLink, RouterOutlet], 
    selector: 'my-app', 
    template: ` 
<a [routerLink]="['/Home']">Home</a> 
<a [routerLink]="['/Login']">Login</a> 
<router-outlet></router-outlet>`, 
}) 
@RouteConfig([ 
    {path: '/home', component: HomeComponent, name: 'Home', useAsDefault: true}, 
    {path: '/login', component: LoginComponent, name: 'Login'}, 
]) 
export class App { 
} 
+0

Ich habe das versucht und ich bekomme diesen Fehler: debuggen.html: 38 Fehlgeschlagen: Kein Provider für ApplicationRef! (LoginComponent -> Router -> RouteRegistry -> Token RouterPrimaryComponent -> ApplicationRef) Fehler: DI Exception –

+0

Sorry, kann nicht reproduzieren. –

Verwandte Themen