我正在使用 okta 库在 Angular8 中进行身份验证。到目前为止,功能运行良好,但项目要求是在 Angular8 中编写单元测试用例。下面是我的服务组件和规范文件的代码。
我正在创建一项公共服务(AccessCheck 服务),在其中检查来自 okta 库的用户访问并将结果返回给组件。使用该结果我在我的应用程序中进行 api 调用。当我运行应用程序时,功能运行正常。
但是当我在 Angular 中运行单元测试的基本设置时,它在 okta 的服务调用中失败并给出错误 okta get user is not a function。我不知道如何用角度为第三方库编写测试用例。任何帮助将不胜感激
我的代码
Access-CheckService.ts
@Injectable({
providedIn: 'root'
})
export class AccessCheckService {
constructor(private router: Router,
private oktaAuth: OktaAuthService, private commonService: CommonService) { }
async checkUserAcess() {
let userAccess = {
adminFlag: false,
isOnlyuserRole: false
}
await this.oktaAuth.getUser().then((user) => {
localStorage.setItem("userAcces", JSON.stringify(userAccess))
return userAccess
})
async checkAdGroupsandProjectIds() {
let projectDetails = JSON.parse(localStorage.getItem('ProjectDetails'))
let userRole = JSON.parse(localStorage.getItem('userAcces'))
if (!userRole) {
userRole = await this.checkUserAcess()
}
let obj = {
projectIds: projectDetails ,
isOnlyuserRole: userRole
}
return obj
}
JobDetials.component.ts
export class JobDetailsComponent implements OnInit {
constructor(private jobDetailsService: JobDetailsService, private formBuilder: FormBuilder, private route: ActivatedRoute,
private commonService: CommonService,private router: Router,
private accessCheck:AccessCheckService) { }
async ngOnInit() {
let userRoles = await this.accessCheck.checkAdGroupsandProjectIds()
this.route.paramMap.subscribe(params => {
this.details_id = params.get("id")
});
if(!userRoles.isOnlyuserRole){
this.getJobDetails(this.details_id,userRoles.projectIds,userRoles.isAdminFlag);
}
}
JobDetails.component.spec.ts
describe('JobDetailsComponent', () => {
let component: JobDetailsComponent;
let fixture: ComponentFixture<JobDetailsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [JobDetailsComponent],
imports: [RouterTestingModule, MaterialModule, BrowserAnimationsModule, FormsModule, ReactiveFormsModule, HttpClientTestingModule,MatSnackBarModule],
schemas: [ NO_ERRORS_SCHEMA ],
providers: [{ provide: OktaAuthService, useValue: environment },AccessCheckService]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(JobDetailsComponent);
component = fixture.componentInstance;
fixture.detectChanges()
});
it('should have job details component', () => {
expect(component).toBeTruthy();
});
it('should have a title', () => {
const compiled = fixture.nativeElement;
fixture.detectChanges(); /// failing here
expect(compiled.querySelector('.title-container .title').textContent).toContain('Job Details:');
});
环境.ts
export const environment = {
oktaIssuer: 'https://identity.mycompany.net',
// oktaRedirectUrl: 'https://mycompany.net/signin',
oktaRedirectUrl: 'http://localhost:4200/signin',
oktaClientId: '1234Id',
production: false
};
对于规范文件中编写的每个测试用例,我都会收到如下错误
TypeError: this.oktaAuth.getUser is not a function
TypeError: this.oktaAuth.getUser is not a function
at AccessCheckService.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/services/accesscheck.service.ts:24:29)
如果我将规范文件中的提供者数组更改为
schemas: [ NO_ERRORS_SCHEMA ],
providers: [OktaAuthService,AccessCheckService]
然后错误变为
your okta url is missing. you can copy your domain from the okta developer console
我知道这个问题很老了,但我想我会为将来查找这个问题的人回答这个问题。解决此问题的方法是添加 OktaAuth 作为提供程序并使用 Jasmin 间谍来模拟 get 用户调用,如下所示:
{
provide: OKTA_AUTH,
useFactory: () => {
const mockService = jasmine.createSpyObj('OktaAuth', ['getUser']);
mockService.getUser.and.callFake(() => Promise.resolve({ name: 'Test' }));
return mockService;
}
}
只需将其添加到您的单元测试提供程序数组中,您就可以开始了。
要在上面 Joe Alvini 的答案中添加一点,他的答案对我有用,但我们在 Angular 应用程序中使用 jest 而不是 jasmine,所以我必须稍微修改他的答案才能为我们工作,这里是:
{
provide: OKTA_AUTH,
useFactory: () => {
const mockService = {
getUser: jest
.fn()
.mockReturnValue(Promise.resolve({ name: 'Test' })),
};
return mockService;
},
},