'How to spy OKTA authStateService.authState$ in angular unit testing using karma jasmine

I have the below authentication guard in my angular application which using OKTA to authenticate.

    export class AuthenticationGuard implements canActivate {

    iaAuthenticated: boolean;
    userDetails: any = null;

    constructor(@Inject(OKTA_AUTH) private oktaAuth: OktaAuth, public authStateService:
        OktaAuthStateServuce) { }
    canActivate = async (next: aCtivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any>
        => {
        try {
            this.authStateService.authState$.subscribe(
                (response) => {
                    this.isAuthenticated = response.isAuthenticated;
                }
            );
            if (this.isAuthenticated) {
                this.userDetails = this.oktaAuth.getUser();
            } else { return false; }
        } catch { return false; }
     }
    }

and this is the spec code for the same which I written

    export class OktaAuthMock {
    isAuthenticated() {
        return true;
    }
    getUser() {
        return {
            email: ‘[email protected]’,
            name: ‘test’
        };
    }
    };

     authState$(){ 
       return {isAuthenticated: true}
     }

    fdescribe(‘test AuthenticationGuard’, () => {
    let service: AuthenticationGuard;
    beforeEach(() => {
        Testbed.configureTestingModule({
            Imports: [HttpClientTestingModule],
            Providers: [
                {
                    provide: OktaAuthStateService,
                    useClass: OktaAuthMock
                },
                {
                    Provide: OKTA_AUTH,
                    useValue: {}
                }
            ]
        )};
        service = Testbed.inject(AuthenticationGurad)
    });

    it(‘test canActivate method’, () => {
        const authService: OktaAuthStateService = Testbed.inject(OktaAuthStateService);
        spyOn<any>(authService. ‘authState$’).and.returnValue(of({ isAuthenticated: true }));
        service.canActivate(null, null);
        expect(service.canActivate).tobeTruthy();
    }); 
    )};

There is no error in the code but I tried to spyon the OktaAuthStateService like above and the lines of code in ts is not covered in unit test. Kindly help to do it correctly.



Solution 1:[1]

It looks like there might be a few items to address here.

  1. Regarding your specific question about mocking Okta, you need to provide mocks for both OKTA_AUTH and OktaStateService. The mocks should match the calls being made. For example, you mocked a method authState$(), but in the OktaStateService, it's not a method, it's a property on the class.
  2. You also haven't provided a mock for OKTA_AUTH. You'll want to do so, which will allow you to test this without importing the HttpClientTestingModule.
  3. Your casing and spelling of the properties and definitions should be double-checked in both your guard as well as your test.
  4. FWIW, if you are creating a guard, consider implementing from CanActivate. Or maybe this is a casing issue?

Here are some samples to reference as you work through this.

An example repo that shows how to implement a guard using Okta is oktadev/okta-angular-material-login-example. This is using an older version of the okta-angular SDK that doesn't use the OKTA_AUTH injection token, so you'll need to make appropriate adjustments. Of note look at

For examples of how to mock and spy on properties in Okta services, check out oktadev/okta-angular-dynamic-components-example. Of note look at

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AlisaDuncan