2017-05-04 2 views
0

Ich arbeite derzeit an einer Angular4-Webanwendung, die Auth0 zur Authentifizierung verwendet.Wie testen Angular4-Anwendung mit Auth0-Integration korrekt?

Während die Authentifizierung wie erwartet funktioniert, hat die Integration von Auth0 die Standardtests (Karma-Komponententests) meiner Anwendung unterbrochen (lässt fehlschlagen).

Mein Code sieht wie folgt aus:

// app.component.ts

/* 
* Angular 2 decorators and services 
*/ 
import { 
    Component, 
    ViewEncapsulation 
} from '@angular/core'; 

import { Auth } from './auth.service'; 

/* 
* App Component 
* Top Level Component 
*/ 
@Component({ 
    selector: 'app', 
    providers: [ Auth ], 
    encapsulation: ViewEncapsulation.None, 
    styleUrls: [ 
    './app.component.scss' 
    ], 
    template: ` 
    <div class="container-fluid"> 
     <router-outlet></router-outlet> 
    </div> 
    ` 
}) 
export class AppComponent { 
    public angularclassLogo = 'assets/img/ExampleApp_smallLogo.png'; 
    public name = 'ExampleApp'; 
    public url = 'https://www.example.com/'; 

    constructor(private auth: Auth) { 
    this.auth.handleAuth(); 
    } 
} 

// auth.service.ts

import { Injectable } from '@angular/core'; 
import { tokenNotExpired } from 'angular2-jwt'; 
import { Router } from '@angular/router'; 
import { Http, Headers, RequestOptions, RequestMethod, Response } from '@angular/http'; 
import 'rxjs/add/operator/toPromise'; 
import 'rxjs/add/operator/filter'; 
import Auth0Lock from 'auth0-lock'; 
import Auth0 from 'auth0-js'; 
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 

import { myConfig, postConfig, necessaryRoles } from './auth.config'; 

// Avoid name not found warnings 
// declare var auth0: any; 

@Injectable() 
export class Auth { 
    public lock = new Auth0Lock(myConfig.clientID, myConfig.domain, myConfig.lock); 
    public userProfile: any; 
    public idToken: string; 
    public signUpIncomplete: boolean; 

    // Configure Auth0 
    private auth0 = new Auth0.WebAuth({ 
    domain: myConfig.domain, 
    clientID: myConfig.clientID, 
    redirectUri: myConfig.redirectUri, 
    responseType: myConfig.responseType 
    }); 

    // Create a stream of logged in status to communicate throughout app 
    private loggedIn: boolean; 
    private loggedIn$ = new BehaviorSubject<boolean>(this.loggedIn); 

    constructor(private router: Router, private http: Http) { 
    // Set userProfile attribute of already saved profile 
    this.userProfile = JSON.parse(localStorage.getItem('profile')); 
    } 
    ... 
} 

// app.component.spec

import { NO_ERRORS_SCHEMA } from '@angular/core'; 
import { 
    async, 
    TestBed, 
    ComponentFixture 
} from '@angular/core/testing'; 
import { 
    BaseRequestOptions, 
    HttpModule, 
    Http, 
    XHRBackend, 
} from '@angular/http'; 
import { RouterTestingModule } from '@angular/router/testing'; 
import { MockBackend } from '@angular/http/testing'; 

// Load the implementations that should be tested 
import { AppComponent } from './app.component'; 
import { AppState } from './app.service'; 
import { Auth } from './auth.service'; 

describe(`App`,() => { 
    let comp: AppComponent; 
    let fixture: ComponentFixture<AppComponent>; 

    // async beforeEach 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ AppComponent ], 
     imports: [RouterTestingModule, HttpModule], 
     schemas: [NO_ERRORS_SCHEMA], 
     providers: [ 
     AppState, 
     Auth, 
     MockBackend, 
     BaseRequestOptions, 
     { 
      provide: Http, 
      deps: [MockBackend, BaseRequestOptions], 
      useFactory: 
      (backend: XHRBackend, defaultOptions: BaseRequestOptions) => { 
       return new Http(backend, defaultOptions); 
      } 
     } 
     ] 
    }) 
    .compileComponents(); // compile template and css 
    })); 

    // synchronous beforeEach 
    beforeEach(() => { 
    fixture = TestBed.createComponent(AppComponent); 
    comp = fixture.componentInstance; 

    fixture.detectChanges(); // trigger initial data binding 
    }); 

    it(`should be readly initialized`,() => { 
    expect(fixture).toBeDefined(); 
    expect(comp).toBeDefined(); 
    }); 

    it(`should be ExampleApp`,() => { 
    expect(comp.url).toEqual('https://www.example.com/'); 
    expect(comp.angularclassLogo).toEqual('assets/img/ExampleApp_smallLogo.png'); 
    expect(comp.name).toEqual('ExampleApp'); 
    }); 
}); 

Das Problem ist, dass beide App: sollte leicht initialisiert werden und App: sollte MyApp sein scheitern mit Cannot read property 'WebAuth' of undefined obwohl WebAuth in auth.service.ts definiert ist, die dann in app.component.spec importiert wird.

Fehle ich irgendwelche Import oder Deklaration?

Antwort

1

Ich habe die Fragen endlich selbst gelöst.

Ich musste eine Kopie für den Auth-Dienst erstellen.

Außerdem musste ich die App-Komponente überschreiben, so dass es dieses Mock-Objekt anstelle des echten Auth-Dienstes verwendet.

Daher sieht die Lösung wie folgt:

import { NO_ERRORS_SCHEMA } from '@angular/core'; 
import { 
    async, 
    TestBed, 
    ComponentFixture 
} from '@angular/core/testing'; 
import { 
    BaseRequestOptions, 
    HttpModule, 
    Http, 
    XHRBackend, 
} from '@angular/http'; 
import { RouterTestingModule } from '@angular/router/testing'; 
import { MockBackend } from '@angular/http/testing'; 

// Load the implementations that should be tested 
import { AppComponent } from './app.component'; 
import { Auth } from './auth.service'; 

// Mock our Auth service 
export class MockAuthService { 
    public handleAuth(): void { 
    return; 
    } 
} 

describe(`App`,() => { 
    let comp: AppComponent; 
    let fixture: ComponentFixture<AppComponent>; 

    // async beforeEach 
    beforeEach(async(() => { 
    TestBed 
     .configureTestingModule({ 
     declarations: [ AppComponent ], 
     imports: [RouterTestingModule, HttpModule], 
     schemas: [NO_ERRORS_SCHEMA], 
     providers: [ 
      MockBackend, 
      BaseRequestOptions, 
      { 
      provide: Http, 
      deps: [MockBackend, BaseRequestOptions], 
      useFactory: (backend: XHRBackend, defaultOptions: BaseRequestOptions) => { 
       return new Http(backend, defaultOptions); 
      } 
      } 
     ] 
     }) 
     .overrideComponent(AppComponent, { 
     set: { 
      providers: [{ provide: Auth, useValue: new MockAuthService() }] 
     } 
     }) 
     .compileComponents(); 

    })); 

    // synchronous beforeEach 
    beforeEach(() => { 
    fixture = TestBed.createComponent(AppComponent); 
    comp = fixture.componentInstance; 

    fixture.detectChanges(); // trigger initial data binding 
    }); 

    it(`should be readly initialized`,() => { 
    expect(fixture).toBeDefined(); 
    expect(comp).toBeDefined(); 
    }); 

    it(`should be ExampleApp`,() => { 
    expect(comp.url).toEqual('https://www.example.com/'); 
    expect(comp.angularclassLogo).toEqual('assets/img/ExampleApp_smallLogo.png'); 
    expect(comp.name).toEqual('ExampleApp'); 
    }); 
}); 
+1

Aber die Frage ist - wie Sie Ihre auth.service testen Sie? – Manolis