Mocking TokenManager in latest version of OktaAuth for Angular

I’m trying to add a fake token into the token manager within a unit test in an angular application and can’t seem to find a feasible way to do this properly with the latest version of the Okta angular SDK.

Using the following (updated) versions of the Okta libraries, what method is best to do this in a unit test?

Context:

  • okta/okta-angular: 5.1.1
  • okta/okta-auth-js: 6.0.0
  • angular 11.2.15

In example, here would be my current flow, where I’m at:

1.) First, I spy on the OKTA_AUTH instance I inject through the constructor:
Implementation:

    constructor(@Inject(OKTA_AUTH) public oktaAuthClient: OktaAuth) { }

Test:

        TestBed.configureTestingModule({
            imports: [ OktaAuthModule ],
            providers: [
                { provide: OKTA_CONFIG, multi: false, useFactory: () => {
                    const oktaAuth = new OktaAuth({
                        issuer: "https://test-host/oauth2/default",
                        clientId: "test-client-id",
                        redirectUri: window.location.origin + '/login/callback',
                        pkce: true,
						tokenManager: {
							storage: 'sessionStorage',
							autoRenew: true
						}
                    });
                    return {oktaAuth};
                }},
            ],
        });

2.) Attempt to spy on token manager and mock a return to the “get” method on it:

Implementation:

const tokenManager: TokenManager = this.oktaAuthClient.tokenManager;
const accessToken = await tokenManager.get('accessToken') as AccessToken;   

Test:

const oktaAuthSpyL1 = jasmine.createSpyObj<OktaAuth>('OktaAuth', ['tokenManager']);
const oktaAuthSpyL2 = jasmine.createSpyObj('oktaAuthSpyL1', ['get'])

Not sure what I’m missing, but this doesn’t seem to work at all and the token is always undefined in the test scope. How to do I get the tokenManager.get() to return a token in a test?

Methods I’ve tried to add a token to the token manager:

setTokens:

        const fakeToken: AccessToken = {
            claims: { sub: "sub" },
            scopes: ["openid" ],
            userinfoUrl: "x",
            authorizeUrl: "x",
            expiresAt: 7200,
            accessToken: "valid-token",
            tokenType: "Bearer",
        };
        const tokens = {} as Tokens;
        tokens.accessToken = fakeToken;
        oktaAuthSpyL2.setTokens(tokens);

tokenManager.add:

   const fakeToken: AccessToken = {
            claims: { sub: "sub" },
            scopes: ["openid" ],
            userinfoUrl: "x",
            authorizeUrl: "x",
            expiresAt: 7200,
            accessToken: "valid-token",
            tokenType: "Bearer",
        };
        // assume the level 2 spy here has access to the token manager methods
        oktaAuthSpyL2.add('accessToken', fakeToken);

        const accessToken = await oktaAuthSpyL2.get('accessToken') as AccessToken;
        console.info(accessToken); // undefined

Hi there. I don’t have an example of mocking the TokenManager, but maybe these samples might help point you in the right direction. This is using Karma instead of Jest.

Here’s an example where I mocked working with the session manager.

In the above sample, I created the jasmine.SpyObj and had it return a spy for the session manager property. It looks like TokenManager is also a property so I think (hope) you can use a similar syntax.

Here’s an example of mocking Okta to check user claims just in case that helps too

Awesome, that’s exactly what I needed, thanks!

The only difference for my purposes, is that since I’m using the injection token in my constructor…

    constructor(@Inject(OKTA_AUTH) public oktaAuthClient: OktaAuth) { }

…my provider looked more like this:

{ provide: OKTA_AUTH, useValue: oktaAuthSpy, multi: false }

…as opposed to…

{ provide: OktaAuth, useValue: oktaAuthSpy, multi: false }
1 Like

Glad to hear it worked for you! And thanks for posting the changes you needed to make! You’re right, the linked GH repos aren’t using the latest version of @okta/okta-angular with the injection token, so I appreciate you sharing that tidbit for others to see!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.