Angular 如何绕过auth0登录进行角度测试?
我正在尝试为Angular/Auth0应用程序编写测试。当localStorage中没有任何内容或其令牌过期时,它会将用户定向到auth0域进行登录。但是,我很难模仿用户绕过auth0登录屏幕 app.component.ts:Angular 如何绕过auth0登录进行角度测试?,angular,unit-testing,jasmine,karma-jasmine,auth0,Angular,Unit Testing,Jasmine,Karma Jasmine,Auth0,我正在尝试为Angular/Auth0应用程序编写测试。当localStorage中没有任何内容或其令牌过期时,它会将用户定向到auth0域进行登录。但是,我很难模仿用户绕过auth0登录屏幕 app.component.ts: export class AppComponent { constructor( public auth: AuthService) { auth.handleAuthentication() } } auth.service.ts: export class A
export class AppComponent {
constructor( public auth: AuthService) { auth.handleAuthentication() }
}
auth.service.ts:
export class AuthService {
authConfig = {
clientID: //omitted for privacy,
domain: //omitted for privacy,
callbackURL: window.location.origin + '/home',
apiUrl: //omitted for privacy
}
auth0 = new auth0.WebAuth({
clientID: this.authConfig.clientID,
domain: this.authConfig.domain,
responseType: 'token id_token',
audience: this.authConfig.apiUrl,
redirectUri: this.authConfig.callbackURL,
scope: 'openid profile email',
})
constructor() { }
public login(): void {
this.auth0.authorize()
}
public logout(): void {
localStorage.removeItem('access_token')
localStorage.removeItem('id_token')
localStorage.removeItem('expires_at')
this.login()
}
public handleAuthentication(): void {
if( this.isAuthenticated() ) return
// if the token is old, logout
if(localStorage.getItem('expires_at') && !this.isAuthenticated()) {
this.logout()
} else {
this.auth0.parseHash((err, authResult) => {
// if we didn't just log in, and we don't have an expiration token, login
if(authResult === null && !localStorage.getItem('expires_at')) {
this.login()
}
if(authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult)
}
})
}
}
private setSession(authResult: any): void {
// Set the time that the Access Token will expire at
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime())
localStorage.setItem('sub', authResult.idTokenPayload.sub)
localStorage.setItem('email', authResult.idTokenPayload.sub.split('|')[2])
localStorage.setItem('access_token', authResult.accessToken)
localStorage.setItem('id_token', authResult.idToken)
localStorage.setItem('expires_at', expiresAt)
}
// Check whether the current time is past the access token's expiration time
public isAuthenticated(): boolean {
const expiresAt = JSON.parse(localStorage.getItem('expires_at'))
return new Date().getTime() < expiresAt
}
}
auth.service.spec.ts:
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AuthService } from './auth.service';
import { DebugElement } from '@angular/core';
describe('AuthService', () => {
let service: AuthService;
let authSpy;
let fixture: ComponentFixture<AuthService>;
let debugElement: DebugElement;
beforeAll( () => {
const expiry = JSON.stringify(new Date().setHours(5));
localStorage.setItem('sub', 'sub')
localStorage.setItem('email', 'test@test.com')
localStorage.setItem('access_token', '1234')
localStorage.setItem('id_token', '1234')
localStorage.setItem('expires_at', expiry);
})
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ RouterTestingModule ],
providers: [ AuthService ]
});
service = new AuthService();
authSpy = spyOn(service, 'isAuthenticated').and.returnValue(true);
});
afterAll( () => {
service = null;
})
it('should be created', () => {
const service: AuthService = TestBed.get(AuthService);
console.log('inside auth service spec');
expect(service).toBeTruthy();
});
it ('should return true when all localStorage set', () => {
//this is not returning true even if it gets to run, which 70% of the time it doesn't
expect( service.isAuthenticated() ).toBeTruthy();
});
});
从'@angular/core/testing'导入{TestBed};
从“@angular/router/testing”导入{RouterTestingModule};
从“/auth.service”导入{AuthService};
从“@angular/core”导入{DebugElement};
描述('AuthService',()=>{
let服务:AuthService;
让authSpy;
let夹具:组件夹具;
let-debugElement:debugElement;
以前(()=>{
const expiry=JSON.stringify(new Date().setHours(5));
setItem('sub','sub')
localStorage.setItem('email','test@test.com')
setItem('access_token','1234')
setItem('id\u token','1234')
setItem('expires\u at',expire);
})
在每个之前(()=>{
TestBed.configureTestingModule({
导入:[RouterTestingModule],
提供者:[授权服务]
});
服务=新的AuthService();
authSpy=spyOn(服务,'isAuthenticated')。和.returnValue(true);
});
毕竟(()=>{
服务=空;
})
它('应该创建',()=>{
const-service:AuthService=TestBed.get(AuthService);
log('内部身份验证服务规范');
expect(service.toBeTruthy();
});
它('设置所有本地存储时应返回true',()=>{
//即使它开始运行,也不会返回true,70%的时候它不会返回true
expect(service.isAuthenticated()).toBeTruthy();
});
});
现在,如果我只是在浏览器中运行它,而没有测试,它运行得很好。登录用户,将其路由到/主页。但是测试将我带到auth0登录屏幕(之前可能运行2-6个测试),如果我使用登录,它会显示404:/home
我似乎找不到任何关于auth0、Angular和routing的好测试文档。。。非常感谢您的任何帮助不要在
构造函数中运行auth.handleAuthentication()
,而要在ngOnInit
方法中运行它。这允许您创建组件的实例并测试其功能,而无需发送到登录
我读过的大多数文档都推荐这种方法,并限制在任何服务或组件的构造函数中执行的代码量。在构造函数中运行auth.handleAuthentication()
,而不是在构造函数中运行ngOnInit
方法。这允许您创建组件的实例并测试其功能,而无需发送到登录
我读过的大多数角度文档都推荐这种方法,并限制在任何服务或组件的构造函数中执行的代码量。如果将auth.handleAuthentication()
移动到ngOnInit
而不是构造函数,会发生什么?我想这就是为什么我所看到的所有东西都建议在ngOnInit
中进行操作,而不是在constructor
Oh-wow中进行操作,这样做实际上绕过了测试浏览器中的登录屏幕,并运行了其余的测试!现在我可以开始调试其他测试了。非常感谢。伟大的我在下面输入了答案,以便您可以接受。谢谢如果将auth.handleAuthentication()
移动到ngOnInit
而不是构造函数,会发生什么?我想这就是为什么我所看到的所有东西都建议在ngOnInit
中进行操作,而不是在constructor
Oh-wow中进行操作,这样做实际上绕过了测试浏览器中的登录屏幕,并运行了其余的测试!现在我可以开始调试其他测试了。非常感谢。伟大的我在下面输入了答案,以便您可以接受。谢谢
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AuthService } from './auth.service';
import { DebugElement } from '@angular/core';
describe('AuthService', () => {
let service: AuthService;
let authSpy;
let fixture: ComponentFixture<AuthService>;
let debugElement: DebugElement;
beforeAll( () => {
const expiry = JSON.stringify(new Date().setHours(5));
localStorage.setItem('sub', 'sub')
localStorage.setItem('email', 'test@test.com')
localStorage.setItem('access_token', '1234')
localStorage.setItem('id_token', '1234')
localStorage.setItem('expires_at', expiry);
})
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ RouterTestingModule ],
providers: [ AuthService ]
});
service = new AuthService();
authSpy = spyOn(service, 'isAuthenticated').and.returnValue(true);
});
afterAll( () => {
service = null;
})
it('should be created', () => {
const service: AuthService = TestBed.get(AuthService);
console.log('inside auth service spec');
expect(service).toBeTruthy();
});
it ('should return true when all localStorage set', () => {
//this is not returning true even if it gets to run, which 70% of the time it doesn't
expect( service.isAuthenticated() ).toBeTruthy();
});
});