2017-05-04 54 views
0

我目前正在使用Auth0進行身份驗證的Angular4 Web應用程序。如何使用Auth0集成正確測試Angular4應用程序?

雖然身份驗證按預期工作,但Auth0的集成已斷開(讓失敗)我的應用程序的默認測試(Karma單元測試)。

我的代碼如下:

// 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'); 
    }); 
}); 

問題是, 應用程序:應該被初始化應用程序:應該是MyApp失敗,但Cannot read property 'WebAuth' of undefined儘管WebAuth在auth.service.ts中定義,然後導入到app.component.spec中。

我是否缺少任何導入或聲明?

回答

1

我終於自己解決了問題。我不得不爲驗證服務創建一個模擬。

此外,我必須重寫App組件,以便它使用該模擬對象而不是真正的Auth服務。

因此該解決方案如下所示:

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

但問題是 - 你怎麼測試auth.service? – Manolis

相關問題