How to mock OktaAuthService for Angular unit test

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

Hello Mraible,

I have one relaed issue with okta null injection error in our service file. Whole code is here in below link:

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!

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?

Ya its there, so it was working for older version, only I tried to replace logout to signOut and it broke with CORS. :frowning:

Old version working

this.oktaAuthService.logout('/logged-out');

What’s the CORS error in your browser console?

The okts signout function is accessing our app url with revoke end point, and resulting CORS error.

@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.

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