I have a service in an Angular 8 App that I’m writing a unit test for. This service has OktaAuthService injected as a dependency.
constructor(private signalRMessagesService: SignalRMessagesService,
private appDataService: ApplicationDataService,
private logger: LogService,
private oktaAuth: **OktaAuthService**) {...
Here’s the unit test:
describe('SignalRService', () => {
let service: SignalRService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule ],
providers: [SignalRMessagesService, ApplicationDataServiceMock, LogServiceMock, OktaAuthServiceMock]
});
service = TestBed.get(SignalRService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
And in the unit test for this service, I am trying to mock OktaAuthService like this:
import { OktaAuthService } from "@okta/okta-angular";
class MockOktaAuthService extends OktaAuthService {
public getAccessToken() {
return new Promise<string | undefined>((resolve) => { resolve('SUPERCOOLTOKEN'); });
};
}
const OktaAuthServiceMock = { provide: OktaAuthService, useClass: MockOktaAuthService };
export default OktaAuthServiceMock;
This mock is consistent with other service mocks we have for other modules, but when I run ng test, and run jasmine test suite, the test fails with the following error:
NullInjectorError: StaticInjectorError(DynamicTestModule)[OktaAuthService -> InjectionToken okta.config.angular]:
StaticInjectorError(Platform: core)[OktaAuthService -> InjectionToken okta.config.angular]:
NullInjectorError: No provider for InjectionToken okta.config.angular! in http://localhost:9876/_karma_webpack_/vendor.js (line 71855)
Any ideas on how to successfully mock OktaAuthService greatfully received.
Here’s how I’ve done it:
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { OKTA_CONFIG, OktaAuthModule } from '@okta/okta-angular';
describe('AppComponent', () => {
const oktaConfig = {
issuer: 'https://not-real.okta.com',
clientId: 'fake-client-id',
redirectUri: 'http://localhost:4200'
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
OktaAuthModule
],
declarations: [
AppComponent
],
providers: [{provide: OKTA_CONFIG, useValue: oktaConfig}]
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'ng-demo'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('ng-demo');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('ng-demo app is running!');
});
});
I just realized you’re asking about the OktaAuthService
, not the OktaAuthModule
. Sorry about that. I don’t have code that shows how to mock it.
1 Like
gkumar
October 28, 2022, 9:38am
4
Hello Mraible,
I have one relaed issue with okta null injection error in our service file. Whole code is here in below link:
Hi Alisa,
As per custService is concern, it simple grabs access token from okta and calls a http request and returns an observable.
We are not using OktaAuthStateService to get the state of login and logout. We are using SSO.
custService.ts
export class CService {
constructor(private http: HttpClient,
@Inject(OKTA_AUTH) private oktaAuth: OktaAuth) {}
getStore(storeId: number): Observable<StoreDealer> {
return from(
this.oktaAuth.getAccessToken()).pipe(
switchMap(acc…
Please help me on this part.
Thanks
Gautam
It looks like you got everything working on the referenced thread. Please let me know if you have any other questions!
gkumar
November 8, 2022, 6:50am
6
Hi Mraible,
The new problem, i m facing is related to
import
import { OKTA_AUTH } from '@okta/okta-angular';
import { OktaAuth } from '@okta/okta-auth-js';
constructor
constructor(
@Inject(OKTA_AUTH) public oktaAuth: OktaAuth,
private router: Router) { }
async logout(){
await this.oktaAuth.signOut({postLogoutRedirectUri: '/logged-out'});
}
or
async logout(){
await this.oktaAuth.signOut();
this.router.navigateByUrl('/logged-out');
}
SignOut function is accessing below url
Request URL: https://blablabla.okta.com/oauth2/ssdscrfbmulibdt/v1/revoke
Resulting CORS error now with signOut() but for earlier version it was working
Older version OktaAuthService
this.oktaAuthService.logout('/logged-out');
No CORS error with above code .
only i replaced the above line with signOut function in latest version of okta, it started giving CORS error for revoke.
Thanks
Gautam
Did you add your app’s URL as a trusted origin?
gkumar
November 8, 2022, 4:45pm
8
Ya its there, so it was working for older version, only I tried to replace logout to signOut and it broke with CORS.
Old version working
this.oktaAuthService.logout('/logged-out');
What’s the CORS error in your browser console?
gkumar
November 9, 2022, 11:16am
10
The okts signout function is accessing our app url with revoke end point, and resulting CORS error.
gkumar
November 9, 2022, 11:26am
11
@mraible below are the screenshots of CORS error:
Should I need to add https://blablabla.com/signout redirectUri as well on okta?
coz currently we have logout as redirectUri.
andrea
December 21, 2022, 6:29pm
12
You’ll need to add your application domain as a Trusted Origin for CORS to allow the SDK to make the CORS request to revoke the token