如何使用 then 块对返回 Promise 的函数进行单元测试
How to unit test a function returning a Promise with then block
我有这段代码可以使用 OAuth2 初始化身份验证,并在进入我的应用程序之前将用户重定向到身份验证服务器
import {Component} from '@angular/core';
import {JwksValidationHandler, OAuthService} from 'angular-oauth2-oidc';
import {authConfig} from './sso.config';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor(private oauthService: OAuthService) {}
async initAuth(): Promise<any> {
return new Promise<void>((resolveFn, rejectFn) => {
this.oauthService.configure(authConfig);
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
this.oauthService.loadDiscoveryDocumentAndTryLogin().then(() => {
if (this.oauthService.hasValidAccessToken()) { // ----------------> My test can't get in this part
this.oauthService.setupAutomaticSilentRefresh();
resolveFn();
}else {
this.oauthService.initCodeFlow();
rejectFn();
}
});// --------------------------------> It goes directly here and gives me: SPEC HAS NO EXPECTATIONS
});
}
}
我想使用 Jasmine 和 Karma 对这部分进行单元测试,我的测试如下:
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
const oauthServiceMock = {
oauthService: {
loadDiscoveryDocumentAndTryLogin(): Promise<true> {
return new Promise<true>(resolve => resolve());
}
}
};
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [OAuthModule.forRoot(), HttpClientTestingModule],
providers: [
{provide: AppComponent, useValue: oauthServiceMock}
],
declarations: [
AppComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('Test for initAuth', fakeAsync(() => {
const spy = spyOn(oauthServiceMock.oauthService, 'loadDiscoveryDocumentAndTryLogin').and.returnValue(Promise.resolve(true));
component.initAuth().then(() => {
tick(5000);
expect(spy).toHaveBeenCalled();
});
}));
});
我的测试进不去块那我不知道我错过了什么。
我认为您提供的模拟函数不正确。
改变这个:
const oauthServiceMock = {
oauthService: {
loadDiscoveryDocumentAndTryLogin(): Promise<true> {
return new Promise<true>(resolve => resolve());
}
}
};
为此:
oauthService: {
loadDiscoveryDocumentAndTryLogin(): Promise<true> {
return new Promise<true>(resolve => resolve());
}
}
并更改此:
providers: [
{provide: AppComponent, useValue: oauthServiceMock}
],
为此:
providers: [
{provide: OAuthService, useValue: oauthServiceMock}
],
我们需要为 OAuthService
而不是 AppComponent
提供模拟。这应该有望解决您的问题。
我有这段代码可以使用 OAuth2 初始化身份验证,并在进入我的应用程序之前将用户重定向到身份验证服务器
import {Component} from '@angular/core';
import {JwksValidationHandler, OAuthService} from 'angular-oauth2-oidc';
import {authConfig} from './sso.config';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor(private oauthService: OAuthService) {}
async initAuth(): Promise<any> {
return new Promise<void>((resolveFn, rejectFn) => {
this.oauthService.configure(authConfig);
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
this.oauthService.loadDiscoveryDocumentAndTryLogin().then(() => {
if (this.oauthService.hasValidAccessToken()) { // ----------------> My test can't get in this part
this.oauthService.setupAutomaticSilentRefresh();
resolveFn();
}else {
this.oauthService.initCodeFlow();
rejectFn();
}
});// --------------------------------> It goes directly here and gives me: SPEC HAS NO EXPECTATIONS
});
}
}
我想使用 Jasmine 和 Karma 对这部分进行单元测试,我的测试如下:
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
const oauthServiceMock = {
oauthService: {
loadDiscoveryDocumentAndTryLogin(): Promise<true> {
return new Promise<true>(resolve => resolve());
}
}
};
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [OAuthModule.forRoot(), HttpClientTestingModule],
providers: [
{provide: AppComponent, useValue: oauthServiceMock}
],
declarations: [
AppComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('Test for initAuth', fakeAsync(() => {
const spy = spyOn(oauthServiceMock.oauthService, 'loadDiscoveryDocumentAndTryLogin').and.returnValue(Promise.resolve(true));
component.initAuth().then(() => {
tick(5000);
expect(spy).toHaveBeenCalled();
});
}));
});
我的测试进不去块那我不知道我错过了什么。
我认为您提供的模拟函数不正确。
改变这个:
const oauthServiceMock = {
oauthService: {
loadDiscoveryDocumentAndTryLogin(): Promise<true> {
return new Promise<true>(resolve => resolve());
}
}
};
为此:
oauthService: {
loadDiscoveryDocumentAndTryLogin(): Promise<true> {
return new Promise<true>(resolve => resolve());
}
}
并更改此:
providers: [
{provide: AppComponent, useValue: oauthServiceMock}
],
为此:
providers: [
{provide: OAuthService, useValue: oauthServiceMock}
],
我们需要为 OAuthService
而不是 AppComponent
提供模拟。这应该有望解决您的问题。